1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _BGFX_VECTOR_B3IVECTOR_HXX
25 #define _BGFX_VECTOR_B3IVECTOR_HXX
26 
27 #include <basegfx/tuple/b3ituple.hxx>
28 #include <basegfx/basegfxdllapi.h>
29 
30 namespace basegfx
31 {
32 	// predeclaration
33 	class B3DHomMatrix;
34 
35 	/** Base Point class with three sal_Int32 values
36 
37 		This class derives all operators and common handling for
38 		a 3D data class from B3ITuple. All necessary extensions
39 		which are special for 3D Vectors are added here.
40 
41 		@see B3ITuple
42 	*/
43 	class BASEGFX_DLLPUBLIC B3IVector : public ::basegfx::B3ITuple
44 	{
45 	public:
46 		/**	Create a 3D Vector
47 
48         	The vector is initialized to (0, 0, 0)
49 		*/
B3IVector()50 		B3IVector()
51 		:	B3ITuple()
52 		{}
53 
54 		/**	Create a 3D Vector
55 
56 			@param nX
57 			This parameter is used to initialize the X-coordinate
58 			of the 3D Vector.
59 
60 			@param nY
61 			This parameter is used to initialize the Y-coordinate
62 			of the 3D Vector.
63 
64 			@param nZ
65 			This parameter is used to initialize the Z-coordinate
66 			of the 3D Vector.
67 		*/
B3IVector(sal_Int32 nX,sal_Int32 nY,sal_Int32 nZ)68 		B3IVector(sal_Int32 nX, sal_Int32 nY, sal_Int32 nZ)
69 		:	B3ITuple(nX, nY, nZ)
70 		{}
71 
72 		/**	Create a copy of a 3D Vector
73 
74 			@param rVec
75 			The 3D Vector which will be copied.
76 		*/
B3IVector(const B3IVector & rVec)77 		B3IVector(const B3IVector& rVec)
78 		:	B3ITuple(rVec)
79 		{}
80 
81 		/** constructor with tuple to allow copy-constructing
82 			from B3ITuple-based classes
83 		*/
B3IVector(const::basegfx::B3ITuple & rTuple)84 		B3IVector(const ::basegfx::B3ITuple& rTuple)
85 		:	B3ITuple(rTuple)
86 		{}
87 
~B3IVector()88 		~B3IVector()
89 		{}
90 
91 		/** *=operator to allow usage from B3IVector, too
92 		*/
operator *=(const B3IVector & rPnt)93 		B3IVector& operator*=( const B3IVector& rPnt )
94 		{
95 			mnX *= rPnt.mnX;
96 			mnY *= rPnt.mnY;
97 			mnZ *= rPnt.mnZ;
98 			return *this;
99 		}
100 
101 		/** *=operator to allow usage from B3IVector, too
102 		*/
operator *=(sal_Int32 t)103 		B3IVector& operator*=(sal_Int32 t)
104 		{
105 			mnX *= t;
106 			mnY *= t;
107 			mnZ *= t;
108 			return *this;
109 		}
110 
111 		/** assignment operator to allow assigning the results
112 			of B3ITuple calculations
113 		*/
operator =(const::basegfx::B3ITuple & rVec)114 		B3IVector& operator=( const ::basegfx::B3ITuple& rVec )
115 		{
116 			mnX = rVec.getX();
117 			mnY = rVec.getY();
118 			mnZ = rVec.getZ();
119 			return *this;
120 		}
121 
122 		/** Calculate the length of this 3D Vector
123 
124 			@return The Length of the 3D Vector
125 		*/
getLength(void) const126 		double getLength(void) const
127 		{
128 			double fLen(scalar(*this));
129 			if((0 == fLen) || (1.0 == fLen))
130 				return fLen;
131 			return sqrt(fLen);
132 		}
133 
134 		/** Calculate the length in the XY-Plane for this 3D Vector
135 
136 			@return The XY-Plane Length of the 3D Vector
137 		*/
getXYLength(void) const138 		double getXYLength(void) const
139 		{
140 			double fLen((mnX * mnX) + (mnY * mnY));
141 			if((0 == fLen) || (1.0 == fLen))
142 				return fLen;
143 			return sqrt(fLen);
144 		}
145 
146 		/** Calculate the length in the XZ-Plane for this 3D Vector
147 
148 			@return The XZ-Plane Length of the 3D Vector
149 		*/
getXZLength(void) const150 		double getXZLength(void) const
151 		{
152 			double fLen((mnX * mnZ) + (mnY * mnZ));
153 			if((0 == fLen) || (1.0 == fLen))
154 				return fLen;
155 			return sqrt(fLen);
156 		}
157 
158 		/** Calculate the length in the YZ-Plane for this 3D Vector
159 
160 			@return The YZ-Plane Length of the 3D Vector
161 		*/
getYZLength(void) const162 		double getYZLength(void) const
163 		{
164 			double fLen((mnY * mnY) + (mnZ * mnZ));
165 			if((0 == fLen) || (1.0 == fLen))
166 				return fLen;
167 			return sqrt(fLen);
168 		}
169 
170 		/** Set the length of this 3D Vector
171 
172 			@param fLen
173 			The to be achieved length of the 3D Vector
174 		*/
setLength(double fLen)175 		B3IVector& setLength(double fLen)
176 		{
177 			double fLenNow(scalar(*this));
178 
179 			if(!::basegfx::fTools::equalZero(fLenNow))
180 			{
181 				const double fOne(1.0);
182 
183 				if(!::basegfx::fTools::equal(fOne, fLenNow))
184 				{
185 					fLen /= sqrt(fLenNow);
186 				}
187 
188 				mnX = fround(mnX*fLen);
189 				mnY = fround(mnY*fLen);
190 				mnZ = fround(mnZ*fLen);
191 			}
192 
193 			return *this;
194 		}
195 
196 		/** Calculate the Scalar product
197 
198 			This method calculates the Scalar product between this
199 			and the given 3D Vector.
200 
201 			@param rVec
202 			A second 3D Vector.
203 
204 			@return
205 			The Scalar Product of two 3D Vectors
206 		*/
scalar(const B3IVector & rVec) const207 		double scalar(const B3IVector& rVec) const
208 		{
209 			return ((mnX * rVec.mnX) + (mnY * rVec.mnY) + (mnZ * rVec.mnZ));
210 		}
211 
212 		/** Transform vector by given transformation matrix.
213 
214         	Since this is a vector, translational components of the
215         	matrix are disregarded.
216 		*/
217 		B3IVector& operator*=( const B3DHomMatrix& rMat );
218 
getEmptyVector()219 		static const B3IVector& getEmptyVector()
220 		{
221 			return (const B3IVector&) ::basegfx::B3ITuple::getEmptyTuple();
222 		}
223 	};
224 
225 	// external operators
226 	//////////////////////////////////////////////////////////////////////////
227 
228 	/** Transform vector by given transformation matrix.
229 
230 		Since this is a vector, translational components of the
231     	matrix are disregarded.
232 	*/
233 	BASEGFX_DLLPUBLIC B3IVector operator*( const B3DHomMatrix& rMat, const B3IVector& rVec );
234 
235 	/** Calculate the Cross Product of two 3D Vectors
236 
237 		@param rVecA
238 		A first 3D Vector.
239 
240 		@param rVecB
241 		A second 3D Vector.
242 
243 		@return
244 		The Cross Product of both 3D Vectors
245 	*/
cross(const B3IVector & rVecA,const B3IVector & rVecB)246 	inline B3IVector cross(const B3IVector& rVecA, const B3IVector& rVecB)
247 	{
248 		B3IVector aVec(
249 			rVecA.getY() * rVecB.getZ() - rVecA.getZ() * rVecB.getY(),
250 			rVecA.getZ() * rVecB.getX() - rVecA.getX() * rVecB.getZ(),
251 			rVecA.getX() * rVecB.getY() - rVecA.getY() * rVecB.getX());
252 		return aVec;
253 	}
254 } // end of namespace basegfx
255 
256 #endif /* _BGFX_VECTOR_B3DVECTOR_HXX */
257