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 
29 namespace basegfx
30 {
31 	// predeclaration
32 	class B3DHomMatrix;
33 
34 	/** Base Point class with three sal_Int32 values
35 
36 		This class derives all operators and common handling for
37 		a 3D data class from B3ITuple. All necessary extensions
38 		which are special for 3D Vectors are added here.
39 
40 		@see B3ITuple
41 	*/
42 	class B3IVector : public ::basegfx::B3ITuple
43 	{
44 	public:
45 		/**	Create a 3D Vector
46 
47         	The vector is initialized to (0, 0, 0)
48 		*/
B3IVector()49 		B3IVector()
50 		:	B3ITuple()
51 		{}
52 
53 		/**	Create a 3D Vector
54 
55 			@param nX
56 			This parameter is used to initialize the X-coordinate
57 			of the 3D Vector.
58 
59 			@param nY
60 			This parameter is used to initialize the Y-coordinate
61 			of the 3D Vector.
62 
63 			@param nZ
64 			This parameter is used to initialize the Z-coordinate
65 			of the 3D Vector.
66 		*/
B3IVector(sal_Int32 nX,sal_Int32 nY,sal_Int32 nZ)67 		B3IVector(sal_Int32 nX, sal_Int32 nY, sal_Int32 nZ)
68 		:	B3ITuple(nX, nY, nZ)
69 		{}
70 
71 		/**	Create a copy of a 3D Vector
72 
73 			@param rVec
74 			The 3D Vector which will be copied.
75 		*/
B3IVector(const B3IVector & rVec)76 		B3IVector(const B3IVector& rVec)
77 		:	B3ITuple(rVec)
78 		{}
79 
80 		/** constructor with tuple to allow copy-constructing
81 			from B3ITuple-based classes
82 		*/
B3IVector(const::basegfx::B3ITuple & rTuple)83 		B3IVector(const ::basegfx::B3ITuple& rTuple)
84 		:	B3ITuple(rTuple)
85 		{}
86 
~B3IVector()87 		~B3IVector()
88 		{}
89 
90 		/** *=operator to allow usage from B3IVector, too
91 		*/
operator *=(const B3IVector & rPnt)92 		B3IVector& operator*=( const B3IVector& rPnt )
93 		{
94 			mnX *= rPnt.mnX;
95 			mnY *= rPnt.mnY;
96 			mnZ *= rPnt.mnZ;
97 			return *this;
98 		}
99 
100 		/** *=operator to allow usage from B3IVector, too
101 		*/
operator *=(sal_Int32 t)102 		B3IVector& operator*=(sal_Int32 t)
103 		{
104 			mnX *= t;
105 			mnY *= t;
106 			mnZ *= t;
107 			return *this;
108 		}
109 
110 		/** assignment operator to allow assigning the results
111 			of B3ITuple calculations
112 		*/
operator =(const::basegfx::B3ITuple & rVec)113 		B3IVector& operator=( const ::basegfx::B3ITuple& rVec )
114 		{
115 			mnX = rVec.getX();
116 			mnY = rVec.getY();
117 			mnZ = rVec.getZ();
118 			return *this;
119 		}
120 
121 		/** Calculate the length of this 3D Vector
122 
123 			@return The Length of the 3D Vector
124 		*/
getLength(void) const125 		double getLength(void) const
126 		{
127 			double fLen(scalar(*this));
128 			if((0 == fLen) || (1.0 == fLen))
129 				return fLen;
130 			return sqrt(fLen);
131 		}
132 
133 		/** Calculate the length in the XY-Plane for this 3D Vector
134 
135 			@return The XY-Plane Length of the 3D Vector
136 		*/
getXYLength(void) const137 		double getXYLength(void) const
138 		{
139 			double fLen((mnX * mnX) + (mnY * mnY));
140 			if((0 == fLen) || (1.0 == fLen))
141 				return fLen;
142 			return sqrt(fLen);
143 		}
144 
145 		/** Calculate the length in the XZ-Plane for this 3D Vector
146 
147 			@return The XZ-Plane Length of the 3D Vector
148 		*/
getXZLength(void) const149 		double getXZLength(void) const
150 		{
151 			double fLen((mnX * mnZ) + (mnY * mnZ));
152 			if((0 == fLen) || (1.0 == fLen))
153 				return fLen;
154 			return sqrt(fLen);
155 		}
156 
157 		/** Calculate the length in the YZ-Plane for this 3D Vector
158 
159 			@return The YZ-Plane Length of the 3D Vector
160 		*/
getYZLength(void) const161 		double getYZLength(void) const
162 		{
163 			double fLen((mnY * mnY) + (mnZ * mnZ));
164 			if((0 == fLen) || (1.0 == fLen))
165 				return fLen;
166 			return sqrt(fLen);
167 		}
168 
169 		/** Set the length of this 3D Vector
170 
171 			@param fLen
172 			The to be achieved length of the 3D Vector
173 		*/
setLength(double fLen)174 		B3IVector& setLength(double fLen)
175 		{
176 			double fLenNow(scalar(*this));
177 
178 			if(!::basegfx::fTools::equalZero(fLenNow))
179 			{
180 				const double fOne(1.0);
181 
182 				if(!::basegfx::fTools::equal(fOne, fLenNow))
183 				{
184 					fLen /= sqrt(fLenNow);
185 				}
186 
187 				mnX = fround(mnX*fLen);
188 				mnY = fround(mnY*fLen);
189 				mnZ = fround(mnZ*fLen);
190 			}
191 
192 			return *this;
193 		}
194 
195 		/** Calculate the Scalar product
196 
197 			This method calculates the Scalar product between this
198 			and the given 3D Vector.
199 
200 			@param rVec
201 			A second 3D Vector.
202 
203 			@return
204 			The Scalar Product of two 3D Vectors
205 		*/
scalar(const B3IVector & rVec) const206 		double scalar(const B3IVector& rVec) const
207 		{
208 			return ((mnX * rVec.mnX) + (mnY * rVec.mnY) + (mnZ * rVec.mnZ));
209 		}
210 
211 		/** Transform vector by given transformation matrix.
212 
213         	Since this is a vector, translational components of the
214         	matrix are disregarded.
215 		*/
216 		B3IVector& operator*=( const B3DHomMatrix& rMat );
217 
getEmptyVector()218 		static const B3IVector& getEmptyVector()
219 		{
220 			return (const B3IVector&) ::basegfx::B3ITuple::getEmptyTuple();
221 		}
222 	};
223 
224 	// external operators
225 	//////////////////////////////////////////////////////////////////////////
226 
227 	/** Transform vector by given transformation matrix.
228 
229 		Since this is a vector, translational components of the
230     	matrix are disregarded.
231 	*/
232 	B3IVector operator*( const B3DHomMatrix& rMat, const B3IVector& rVec );
233 
234 	/** Calculate the Cross Product of two 3D Vectors
235 
236 		@param rVecA
237 		A first 3D Vector.
238 
239 		@param rVecB
240 		A second 3D Vector.
241 
242 		@return
243 		The Cross Product of both 3D Vectors
244 	*/
cross(const B3IVector & rVecA,const B3IVector & rVecB)245 	inline B3IVector cross(const B3IVector& rVecA, const B3IVector& rVecB)
246 	{
247 		B3IVector aVec(
248 			rVecA.getY() * rVecB.getZ() - rVecA.getZ() * rVecB.getY(),
249 			rVecA.getZ() * rVecB.getX() - rVecA.getX() * rVecB.getZ(),
250 			rVecA.getX() * rVecB.getY() - rVecA.getY() * rVecB.getX());
251 		return aVec;
252 	}
253 } // end of namespace basegfx
254 
255 #endif /* _BGFX_VECTOR_B3DVECTOR_HXX */
256