xref: /AOO41X/main/basegfx/inc/basegfx/vector/b3dvector.hxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef _BGFX_VECTOR_B3DVECTOR_HXX
29 #define _BGFX_VECTOR_B3DVECTOR_HXX
30 
31 #include <basegfx/tuple/b3dtuple.hxx>
32 
33 //////////////////////////////////////////////////////////////////////////////
34 
35 namespace basegfx
36 {
37 	// predeclaration
38 	class B3DHomMatrix;
39 
40 	/** Base Point class with three double values
41 
42 		This class derives all operators and common handling for
43 		a 3D data class from B3DTuple. All necessary extensions
44 		which are special for 3D Vectors are added here.
45 
46 		@see B3DTuple
47 	*/
48 	class B3DVector : public ::basegfx::B3DTuple
49 	{
50 	public:
51 		/**	Create a 3D Vector
52 
53         	The vector is initialized to (0.0, 0.0, 0.0)
54 		*/
55 		B3DVector()
56 		:	B3DTuple()
57 		{}
58 
59 		/**	Create a 3D Vector
60 
61 			@param fX
62 			This parameter is used to initialize the X-coordinate
63 			of the 3D Vector.
64 
65 			@param fY
66 			This parameter is used to initialize the Y-coordinate
67 			of the 3D Vector.
68 
69 			@param fZ
70 			This parameter is used to initialize the Z-coordinate
71 			of the 3D Vector.
72 		*/
73 		B3DVector(double fX, double fY, double fZ)
74 		:	B3DTuple(fX, fY, fZ)
75 		{}
76 
77 		/**	Create a copy of a 3D Vector
78 
79 			@param rVec
80 			The 3D Vector which will be copied.
81 		*/
82 		B3DVector(const B3DVector& rVec)
83 		:	B3DTuple(rVec)
84 		{}
85 
86 		/** constructor with tuple to allow copy-constructing
87 			from B3DTuple-based classes
88 		*/
89 		B3DVector(const ::basegfx::B3DTuple& rTuple)
90 		:	B3DTuple(rTuple)
91 		{}
92 
93 		~B3DVector()
94 		{}
95 
96 		/** *=operator to allow usage from B3DVector, too
97 		*/
98 		B3DVector& operator*=( const B3DVector& rPnt )
99 		{
100 			mfX *= rPnt.mfX;
101 			mfY *= rPnt.mfY;
102 			mfZ *= rPnt.mfZ;
103 			return *this;
104 		}
105 
106 		/** *=operator to allow usage from B3DVector, too
107 		*/
108 		B3DVector& operator*=(double t)
109 		{
110 			mfX *= t;
111 			mfY *= t;
112 			mfZ *= t;
113 			return *this;
114 		}
115 
116 		/** assignment operator to allow assigning the results
117 			of B3DTuple calculations
118 		*/
119 		B3DVector& operator=( const ::basegfx::B3DTuple& rVec )
120 		{
121 			mfX = rVec.getX();
122 			mfY = rVec.getY();
123 			mfZ = rVec.getZ();
124 			return *this;
125 		}
126 
127 		/** Calculate the length of this 3D Vector
128 
129 			@return The Length of the 3D Vector
130 		*/
131 		double getLength(void) const
132 		{
133 			double fLen(scalar(*this));
134 			if((0.0 == fLen) || (1.0 == fLen))
135 				return fLen;
136 			return sqrt(fLen);
137 		}
138 
139 		/** Calculate the length in the XY-Plane for this 3D Vector
140 
141 			@return The XY-Plane Length of the 3D Vector
142 		*/
143 		double getXYLength(void) const
144 		{
145 			double fLen((mfX * mfX) + (mfY * mfY));
146 			if((0.0 == fLen) || (1.0 == fLen))
147 				return fLen;
148 			return sqrt(fLen);
149 		}
150 
151 		/** Calculate the length in the XZ-Plane for this 3D Vector
152 
153 			@return The XZ-Plane Length of the 3D Vector
154 		*/
155 		double getXZLength(void) const
156 		{
157 			double fLen((mfX * mfX) + (mfZ * mfZ)); // #i73040#
158 			if((0.0 == fLen) || (1.0 == fLen))
159 				return fLen;
160 			return sqrt(fLen);
161 		}
162 
163 		/** Calculate the length in the YZ-Plane for this 3D Vector
164 
165 			@return The YZ-Plane Length of the 3D Vector
166 		*/
167 		double getYZLength(void) const
168 		{
169 			double fLen((mfY * mfY) + (mfZ * mfZ));
170 			if((0.0 == fLen) || (1.0 == fLen))
171 				return fLen;
172 			return sqrt(fLen);
173 		}
174 
175 		/** Set the length of this 3D Vector
176 
177 			@param fLen
178 			The to be achieved length of the 3D Vector
179 		*/
180 		B3DVector& setLength(double fLen)
181 		{
182 			double fLenNow(scalar(*this));
183 
184 			if(!::basegfx::fTools::equalZero(fLenNow))
185 			{
186 				const double fOne(1.0);
187 
188 				if(!::basegfx::fTools::equal(fOne, fLenNow))
189 				{
190 					fLen /= sqrt(fLenNow);
191 				}
192 
193 				mfX *= fLen;
194 				mfY *= fLen;
195 				mfZ *= fLen;
196 			}
197 
198 			return *this;
199 		}
200 
201 		/** Normalize this 3D Vector
202 
203 			The length of the 3D Vector is set to 1.0
204 		*/
205 		B3DVector& normalize();
206 
207 		/** Test if this 3D Vector is normalized
208 
209 			@return
210 			true if lenth of vector is equal to 1.0
211 			false else
212 		*/
213 		bool isNormalized() const
214 		{
215 			const double fOne(1.0);
216 			const double fScalar(scalar(*this));
217 
218 			return (::basegfx::fTools::equal(fOne, fScalar));
219 		}
220 
221 		/** get a 3D Vector which is perpendicular to this and a given 3D Vector
222 
223 			@attention This only works if this and the given 3D Vector are
224 			both normalized.
225 
226 			@param rNormalizedVec
227 			A normalized 3D Vector.
228 
229 			@return
230 			A 3D Vector perpendicular to this and the given one
231 		*/
232 		B3DVector getPerpendicular(const B3DVector& rNormalizedVec) const;
233 
234 		/** get the projection of this Vector on the given Plane
235 
236 			@attention This only works if the given 3D Vector defining
237 			the Plane is normalized.
238 
239 			@param rNormalizedPlane
240 			A normalized 3D Vector defining a Plane.
241 
242 			@return
243 			The projected 3D Vector
244 		*/
245 		B3DVector getProjectionOnPlane(const B3DVector& rNormalizedPlane) const;
246 
247 		/** Calculate the Scalar product
248 
249 			This method calculates the Scalar product between this
250 			and the given 3D Vector.
251 
252 			@param rVec
253 			A second 3D Vector.
254 
255 			@return
256 			The Scalar Product of two 3D Vectors
257 		*/
258 		double scalar(const B3DVector& rVec) const
259 		{
260 			return ((mfX * rVec.mfX) + (mfY * rVec.mfY) + (mfZ * rVec.mfZ));
261 		}
262 
263 		/** Transform vector by given transformation matrix.
264 
265         	Since this is a vector, translational components of the
266         	matrix are disregarded.
267 		*/
268 		B3DVector& operator*=( const B3DHomMatrix& rMat );
269 
270 		static const B3DVector& getEmptyVector()
271 		{
272 			return (const B3DVector&) ::basegfx::B3DTuple::getEmptyTuple();
273 		}
274 	};
275 
276 	// external operators
277 	//////////////////////////////////////////////////////////////////////////
278 
279 	/** get a 3D Vector which is in 2D (ignoring
280 		the Z-Coordinate) perpendicular to a given 3D Vector
281 
282 		@attention This only works if the given 3D Vector is normalized.
283 
284 		@param rNormalizedVec
285 		A normalized 3D Vector.
286 
287 		@return
288 		A 3D Vector perpendicular to the given one in X,Y (2D).
289 	*/
290 	inline B3DVector getPerpendicular2D( const B3DVector& rNormalizedVec )
291 	{
292 		B3DVector aPerpendicular(-rNormalizedVec.getY(), rNormalizedVec.getX(), rNormalizedVec.getZ());
293 		return aPerpendicular;
294 	}
295 
296 	/** Test two vectors which need not to be normalized for parallelism
297 
298 		@param rVecA
299 		The first 3D Vector
300 
301 		@param rVecB
302 		The second 3D Vector
303 
304 		@return
305 		bool if the two values are parallel. Also true if
306 		one of the vectors is empty.
307 	*/
308 	bool areParallel( const B3DVector& rVecA, const B3DVector& rVecB );
309 
310 	/** Transform vector by given transformation matrix.
311 
312 		Since this is a vector, translational components of the
313     	matrix are disregarded.
314 	*/
315 	B3DVector operator*( const B3DHomMatrix& rMat, const B3DVector& rVec );
316 
317 	/** Calculate the Cross Product of two 3D Vectors
318 
319 		@param rVecA
320 		A first 3D Vector.
321 
322 		@param rVecB
323 		A second 3D Vector.
324 
325 		@return
326 		The Cross Product of both 3D Vectors
327 	*/
328 	inline B3DVector cross(const B3DVector& rVecA, const B3DVector& rVecB)
329 	{
330 		B3DVector aVec(
331 			rVecA.getY() * rVecB.getZ() - rVecA.getZ() * rVecB.getY(),
332 			rVecA.getZ() * rVecB.getX() - rVecA.getX() * rVecB.getZ(),
333 			rVecA.getX() * rVecB.getY() - rVecA.getY() * rVecB.getX());
334 		return aVec;
335 	}
336 } // end of namespace basegfx
337 
338 //////////////////////////////////////////////////////////////////////////////
339 
340 #endif /* _BGFX_VECTOR_B3DVECTOR_HXX */
341