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