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