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