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