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