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