Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_BASEGFX_VECTOR_B3DVECTOR_HXX
21 : #define INCLUDED_BASEGFX_VECTOR_B3DVECTOR_HXX
22 :
23 : #include <basegfx/tuple/b3dtuple.hxx>
24 : #include <basegfx/basegfxdllapi.h>
25 :
26 :
27 :
28 : namespace basegfx
29 : {
30 : // predeclaration
31 : class B3DHomMatrix;
32 :
33 : /** Base Point class with three double values
34 :
35 : This class derives all operators and common handling for
36 : a 3D data class from B3DTuple. All necessary extensions
37 : which are special for 3D Vectors are added here.
38 :
39 : @see B3DTuple
40 : */
41 898475 : class BASEGFX_DLLPUBLIC B3DVector : public ::basegfx::B3DTuple
42 : {
43 : public:
44 : /** Create a 3D Vector
45 :
46 : The vector is initialized to (0.0, 0.0, 0.0)
47 : */
48 527455 : B3DVector()
49 527455 : : B3DTuple()
50 527455 : {}
51 :
52 : /** Create a 3D Vector
53 :
54 : @param fX
55 : This parameter is used to initialize the X-coordinate
56 : of the 3D Vector.
57 :
58 : @param fY
59 : This parameter is used to initialize the Y-coordinate
60 : of the 3D Vector.
61 :
62 : @param fZ
63 : This parameter is used to initialize the Z-coordinate
64 : of the 3D Vector.
65 : */
66 420980 : B3DVector(double fX, double fY, double fZ)
67 420980 : : B3DTuple(fX, fY, fZ)
68 420980 : {}
69 :
70 : /** Create a copy of a 3D Vector
71 :
72 : @param rVec
73 : The 3D Vector which will be copied.
74 : */
75 1486596 : B3DVector(const B3DVector& rVec)
76 1486596 : : B3DTuple(rVec)
77 1486596 : {}
78 :
79 : /** constructor with tuple to allow copy-constructing
80 : from B3DTuple-based classes
81 : */
82 989063 : B3DVector(const ::basegfx::B3DTuple& rTuple)
83 989063 : : B3DTuple(rTuple)
84 989063 : {}
85 :
86 3422642 : ~B3DVector()
87 3422642 : {}
88 :
89 : /** *=operator to allow usage from B3DVector, too
90 : */
91 : B3DVector& operator*=( const B3DVector& rPnt )
92 : {
93 : mfX *= rPnt.mfX;
94 : mfY *= rPnt.mfY;
95 : mfZ *= rPnt.mfZ;
96 : return *this;
97 : }
98 :
99 : /** *=operator to allow usage from B3DVector, too
100 : */
101 0 : B3DVector& operator*=(double t)
102 : {
103 0 : mfX *= t;
104 0 : mfY *= t;
105 0 : mfZ *= t;
106 0 : return *this;
107 : }
108 :
109 : /** assignment operator to allow assigning the results
110 : of B3DTuple calculations
111 : */
112 51481 : B3DVector& operator=( const ::basegfx::B3DTuple& rVec )
113 : {
114 51481 : mfX = rVec.getX();
115 51481 : mfY = rVec.getY();
116 51481 : mfZ = rVec.getZ();
117 51481 : return *this;
118 : }
119 :
120 : /** Calculate the length of this 3D Vector
121 :
122 : @return The Length of the 3D Vector
123 : */
124 108868 : double getLength(void) const
125 : {
126 108868 : double fLen(scalar(*this));
127 108868 : if((0.0 == fLen) || (1.0 == fLen))
128 6668 : return fLen;
129 102200 : return sqrt(fLen);
130 : }
131 :
132 : /** Calculate the length in the XY-Plane for this 3D Vector
133 :
134 : @return The XY-Plane Length of the 3D Vector
135 : */
136 : double getXYLength(void) const
137 : {
138 : double fLen((mfX * mfX) + (mfY * mfY));
139 : if((0.0 == fLen) || (1.0 == fLen))
140 : return fLen;
141 : return sqrt(fLen);
142 : }
143 :
144 : /** Calculate the length in the XZ-Plane for this 3D Vector
145 :
146 : @return The XZ-Plane Length of the 3D Vector
147 : */
148 9902 : double getXZLength(void) const
149 : {
150 9902 : double fLen((mfX * mfX) + (mfZ * mfZ)); // #i73040#
151 9902 : if((0.0 == fLen) || (1.0 == fLen))
152 202 : return fLen;
153 9700 : return sqrt(fLen);
154 : }
155 :
156 : /** Calculate the length in the YZ-Plane for this 3D Vector
157 :
158 : @return The YZ-Plane Length of the 3D Vector
159 : */
160 1459 : double getYZLength(void) const
161 : {
162 1459 : double fLen((mfY * mfY) + (mfZ * mfZ));
163 1459 : if((0.0 == fLen) || (1.0 == fLen))
164 1459 : return fLen;
165 0 : return sqrt(fLen);
166 : }
167 :
168 : /** Set the length of this 3D Vector
169 :
170 : @param fLen
171 : The to be achieved length of the 3D Vector
172 : */
173 70 : B3DVector& setLength(double fLen)
174 : {
175 70 : double fLenNow(scalar(*this));
176 :
177 70 : if(!::basegfx::fTools::equalZero(fLenNow))
178 : {
179 70 : const double fOne(1.0);
180 :
181 70 : if(!::basegfx::fTools::equal(fOne, fLenNow))
182 : {
183 70 : fLen /= sqrt(fLenNow);
184 : }
185 :
186 70 : mfX *= fLen;
187 70 : mfY *= fLen;
188 70 : mfZ *= fLen;
189 : }
190 :
191 70 : return *this;
192 : }
193 :
194 : /** Normalize this 3D Vector
195 :
196 : The length of the 3D Vector is set to 1.0
197 : */
198 : B3DVector& normalize();
199 :
200 : /** Test if this 3D Vector is normalized
201 :
202 : @return
203 : true if lenth of vector is equal to 1.0
204 : false else
205 : */
206 : bool isNormalized() const
207 : {
208 : const double fOne(1.0);
209 : const double fScalar(scalar(*this));
210 :
211 : return (::basegfx::fTools::equal(fOne, fScalar));
212 : }
213 :
214 : /** get a 3D Vector which is perpendicular to this and a given 3D Vector
215 :
216 : @attention This only works if this and the given 3D Vector are
217 : both normalized.
218 :
219 : @param rNormalizedVec
220 : A normalized 3D Vector.
221 :
222 : @return
223 : A 3D Vector perpendicular to this and the given one
224 : */
225 : B3DVector getPerpendicular(const B3DVector& rNormalizedVec) const;
226 :
227 : /** Calculate the Scalar product
228 :
229 : This method calculates the Scalar product between this
230 : and the given 3D Vector.
231 :
232 : @param rVec
233 : A second 3D Vector.
234 :
235 : @return
236 : The Scalar Product of two 3D Vectors
237 : */
238 1035926 : double scalar(const B3DVector& rVec) const
239 : {
240 1035926 : return ((mfX * rVec.mfX) + (mfY * rVec.mfY) + (mfZ * rVec.mfZ));
241 : }
242 :
243 : /** Transform vector by given transformation matrix.
244 :
245 : Since this is a vector, translational components of the
246 : matrix are disregarded.
247 : */
248 : B3DVector& operator*=( const B3DHomMatrix& rMat );
249 :
250 151725 : static const B3DVector& getEmptyVector()
251 : {
252 151725 : return static_cast<const B3DVector&>( ::basegfx::B3DTuple::getEmptyTuple() );
253 : }
254 : };
255 :
256 : // external operators
257 :
258 :
259 : /** get a 3D Vector which is in 2D (ignoring
260 : the Z-Coordinate) perpendicular to a given 3D Vector
261 :
262 : @attention This only works if the given 3D Vector is normalized.
263 :
264 : @param rNormalizedVec
265 : A normalized 3D Vector.
266 :
267 : @return
268 : A 3D Vector perpendicular to the given one in X,Y (2D).
269 : */
270 : inline B3DVector getPerpendicular2D( const B3DVector& rNormalizedVec )
271 : {
272 : B3DVector aPerpendicular(-rNormalizedVec.getY(), rNormalizedVec.getX(), rNormalizedVec.getZ());
273 : return aPerpendicular;
274 : }
275 :
276 : /** Test two vectors which need not to be normalized for parallelism
277 :
278 : @param rVecA
279 : The first 3D Vector
280 :
281 : @param rVecB
282 : The second 3D Vector
283 :
284 : @return
285 : bool if the two values are parallel. Also true if
286 : one of the vectors is empty.
287 : */
288 : BASEGFX_DLLPUBLIC bool areParallel( const B3DVector& rVecA, const B3DVector& rVecB );
289 :
290 : /** Transform vector by given transformation matrix.
291 :
292 : Since this is a vector, translational components of the
293 : matrix are disregarded.
294 : */
295 : BASEGFX_DLLPUBLIC B3DVector operator*( const B3DHomMatrix& rMat, const B3DVector& rVec );
296 :
297 : /** Calculate the Cross Product of two 3D Vectors
298 :
299 : @param rVecA
300 : A first 3D Vector.
301 :
302 : @param rVecB
303 : A second 3D Vector.
304 :
305 : @return
306 : The Cross Product of both 3D Vectors
307 : */
308 316170 : inline B3DVector cross(const B3DVector& rVecA, const B3DVector& rVecB)
309 : {
310 : B3DVector aVec(
311 316170 : rVecA.getY() * rVecB.getZ() - rVecA.getZ() * rVecB.getY(),
312 316170 : rVecA.getZ() * rVecB.getX() - rVecA.getX() * rVecB.getZ(),
313 948510 : rVecA.getX() * rVecB.getY() - rVecA.getY() * rVecB.getX());
314 316170 : return aVec;
315 : }
316 : } // end of namespace basegfx
317 :
318 :
319 :
320 : #endif // INCLUDED_BASEGFX_VECTOR_B3DVECTOR_HXX
321 :
322 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|