1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef _BGFX_VECTOR_B3DVECTOR_HXX 29 #define _BGFX_VECTOR_B3DVECTOR_HXX 30 31 #include <basegfx/tuple/b3dtuple.hxx> 32 33 ////////////////////////////////////////////////////////////////////////////// 34 35 namespace basegfx 36 { 37 // predeclaration 38 class B3DHomMatrix; 39 40 /** Base Point class with three double values 41 42 This class derives all operators and common handling for 43 a 3D data class from B3DTuple. All necessary extensions 44 which are special for 3D Vectors are added here. 45 46 @see B3DTuple 47 */ 48 class B3DVector : public ::basegfx::B3DTuple 49 { 50 public: 51 /** Create a 3D Vector 52 53 The vector is initialized to (0.0, 0.0, 0.0) 54 */ 55 B3DVector() 56 : B3DTuple() 57 {} 58 59 /** Create a 3D Vector 60 61 @param fX 62 This parameter is used to initialize the X-coordinate 63 of the 3D Vector. 64 65 @param fY 66 This parameter is used to initialize the Y-coordinate 67 of the 3D Vector. 68 69 @param fZ 70 This parameter is used to initialize the Z-coordinate 71 of the 3D Vector. 72 */ 73 B3DVector(double fX, double fY, double fZ) 74 : B3DTuple(fX, fY, fZ) 75 {} 76 77 /** Create a copy of a 3D Vector 78 79 @param rVec 80 The 3D Vector which will be copied. 81 */ 82 B3DVector(const B3DVector& rVec) 83 : B3DTuple(rVec) 84 {} 85 86 /** constructor with tuple to allow copy-constructing 87 from B3DTuple-based classes 88 */ 89 B3DVector(const ::basegfx::B3DTuple& rTuple) 90 : B3DTuple(rTuple) 91 {} 92 93 ~B3DVector() 94 {} 95 96 /** *=operator to allow usage from B3DVector, too 97 */ 98 B3DVector& operator*=( const B3DVector& rPnt ) 99 { 100 mfX *= rPnt.mfX; 101 mfY *= rPnt.mfY; 102 mfZ *= rPnt.mfZ; 103 return *this; 104 } 105 106 /** *=operator to allow usage from B3DVector, too 107 */ 108 B3DVector& operator*=(double t) 109 { 110 mfX *= t; 111 mfY *= t; 112 mfZ *= t; 113 return *this; 114 } 115 116 /** assignment operator to allow assigning the results 117 of B3DTuple calculations 118 */ 119 B3DVector& operator=( const ::basegfx::B3DTuple& rVec ) 120 { 121 mfX = rVec.getX(); 122 mfY = rVec.getY(); 123 mfZ = rVec.getZ(); 124 return *this; 125 } 126 127 /** Calculate the length of this 3D Vector 128 129 @return The Length of the 3D Vector 130 */ 131 double getLength(void) const 132 { 133 double fLen(scalar(*this)); 134 if((0.0 == fLen) || (1.0 == fLen)) 135 return fLen; 136 return sqrt(fLen); 137 } 138 139 /** Calculate the length in the XY-Plane for this 3D Vector 140 141 @return The XY-Plane Length of the 3D Vector 142 */ 143 double getXYLength(void) const 144 { 145 double fLen((mfX * mfX) + (mfY * mfY)); 146 if((0.0 == fLen) || (1.0 == fLen)) 147 return fLen; 148 return sqrt(fLen); 149 } 150 151 /** Calculate the length in the XZ-Plane for this 3D Vector 152 153 @return The XZ-Plane Length of the 3D Vector 154 */ 155 double getXZLength(void) const 156 { 157 double fLen((mfX * mfX) + (mfZ * mfZ)); // #i73040# 158 if((0.0 == fLen) || (1.0 == fLen)) 159 return fLen; 160 return sqrt(fLen); 161 } 162 163 /** Calculate the length in the YZ-Plane for this 3D Vector 164 165 @return The YZ-Plane Length of the 3D Vector 166 */ 167 double getYZLength(void) const 168 { 169 double fLen((mfY * mfY) + (mfZ * mfZ)); 170 if((0.0 == fLen) || (1.0 == fLen)) 171 return fLen; 172 return sqrt(fLen); 173 } 174 175 /** Set the length of this 3D Vector 176 177 @param fLen 178 The to be achieved length of the 3D Vector 179 */ 180 B3DVector& setLength(double fLen) 181 { 182 double fLenNow(scalar(*this)); 183 184 if(!::basegfx::fTools::equalZero(fLenNow)) 185 { 186 const double fOne(1.0); 187 188 if(!::basegfx::fTools::equal(fOne, fLenNow)) 189 { 190 fLen /= sqrt(fLenNow); 191 } 192 193 mfX *= fLen; 194 mfY *= fLen; 195 mfZ *= fLen; 196 } 197 198 return *this; 199 } 200 201 /** Normalize this 3D Vector 202 203 The length of the 3D Vector is set to 1.0 204 */ 205 B3DVector& normalize(); 206 207 /** Test if this 3D Vector is normalized 208 209 @return 210 true if lenth of vector is equal to 1.0 211 false else 212 */ 213 bool isNormalized() const 214 { 215 const double fOne(1.0); 216 const double fScalar(scalar(*this)); 217 218 return (::basegfx::fTools::equal(fOne, fScalar)); 219 } 220 221 /** get a 3D Vector which is perpendicular to this and a given 3D Vector 222 223 @attention This only works if this and the given 3D Vector are 224 both normalized. 225 226 @param rNormalizedVec 227 A normalized 3D Vector. 228 229 @return 230 A 3D Vector perpendicular to this and the given one 231 */ 232 B3DVector getPerpendicular(const B3DVector& rNormalizedVec) const; 233 234 /** get the projection of this Vector on the given Plane 235 236 @attention This only works if the given 3D Vector defining 237 the Plane is normalized. 238 239 @param rNormalizedPlane 240 A normalized 3D Vector defining a Plane. 241 242 @return 243 The projected 3D Vector 244 */ 245 B3DVector getProjectionOnPlane(const B3DVector& rNormalizedPlane) const; 246 247 /** Calculate the Scalar product 248 249 This method calculates the Scalar product between this 250 and the given 3D Vector. 251 252 @param rVec 253 A second 3D Vector. 254 255 @return 256 The Scalar Product of two 3D Vectors 257 */ 258 double scalar(const B3DVector& rVec) const 259 { 260 return ((mfX * rVec.mfX) + (mfY * rVec.mfY) + (mfZ * rVec.mfZ)); 261 } 262 263 /** Transform vector by given transformation matrix. 264 265 Since this is a vector, translational components of the 266 matrix are disregarded. 267 */ 268 B3DVector& operator*=( const B3DHomMatrix& rMat ); 269 270 static const B3DVector& getEmptyVector() 271 { 272 return (const B3DVector&) ::basegfx::B3DTuple::getEmptyTuple(); 273 } 274 }; 275 276 // external operators 277 ////////////////////////////////////////////////////////////////////////// 278 279 /** get a 3D Vector which is in 2D (ignoring 280 the Z-Coordinate) perpendicular to a given 3D Vector 281 282 @attention This only works if the given 3D Vector is normalized. 283 284 @param rNormalizedVec 285 A normalized 3D Vector. 286 287 @return 288 A 3D Vector perpendicular to the given one in X,Y (2D). 289 */ 290 inline B3DVector getPerpendicular2D( const B3DVector& rNormalizedVec ) 291 { 292 B3DVector aPerpendicular(-rNormalizedVec.getY(), rNormalizedVec.getX(), rNormalizedVec.getZ()); 293 return aPerpendicular; 294 } 295 296 /** Test two vectors which need not to be normalized for parallelism 297 298 @param rVecA 299 The first 3D Vector 300 301 @param rVecB 302 The second 3D Vector 303 304 @return 305 bool if the two values are parallel. Also true if 306 one of the vectors is empty. 307 */ 308 bool areParallel( const B3DVector& rVecA, const B3DVector& rVecB ); 309 310 /** Transform vector by given transformation matrix. 311 312 Since this is a vector, translational components of the 313 matrix are disregarded. 314 */ 315 B3DVector operator*( const B3DHomMatrix& rMat, const B3DVector& rVec ); 316 317 /** Calculate the Cross Product of two 3D Vectors 318 319 @param rVecA 320 A first 3D Vector. 321 322 @param rVecB 323 A second 3D Vector. 324 325 @return 326 The Cross Product of both 3D Vectors 327 */ 328 inline B3DVector cross(const B3DVector& rVecA, const B3DVector& rVecB) 329 { 330 B3DVector aVec( 331 rVecA.getY() * rVecB.getZ() - rVecA.getZ() * rVecB.getY(), 332 rVecA.getZ() * rVecB.getX() - rVecA.getX() * rVecB.getZ(), 333 rVecA.getX() * rVecB.getY() - rVecA.getY() * rVecB.getX()); 334 return aVec; 335 } 336 } // end of namespace basegfx 337 338 ////////////////////////////////////////////////////////////////////////////// 339 340 #endif /* _BGFX_VECTOR_B3DVECTOR_HXX */ 341