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 #pragma once 21 22 #include <basegfx/tuple/b3dtuple.hxx> 23 #include <basegfx/basegfxdllapi.h> 24 25 namespace basegfx 26 { 27 class B3DHomMatrix; 28 29 /** Base Point class with three double values 30 31 This class derives all operators and common handling for 32 a 3D data class from B3DTuple. All necessary extensions 33 which are special for 3D Vectors are added here. 34 35 @see B3DTuple 36 */ 37 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC B3DVector : public ::basegfx::B3DTuple 38 { 39 public: 40 /** Create a 3D Vector 41 42 The vector is initialized to (0.0, 0.0, 0.0) 43 */ B3DVector()44 B3DVector() 45 : B3DTuple() 46 {} 47 48 /** Create a 3D Vector 49 50 @param fX 51 This parameter is used to initialize the X-coordinate 52 of the 3D Vector. 53 54 @param fY 55 This parameter is used to initialize the Y-coordinate 56 of the 3D Vector. 57 58 @param fZ 59 This parameter is used to initialize the Z-coordinate 60 of the 3D Vector. 61 */ B3DVector(double fX,double fY,double fZ)62 B3DVector(double fX, double fY, double fZ) 63 : B3DTuple(fX, fY, fZ) 64 {} 65 66 /** constructor with tuple to allow copy-constructing 67 from B3DTuple-based classes 68 */ B3DVector(const::basegfx::B3DTuple & rTuple)69 B3DVector(const ::basegfx::B3DTuple& rTuple) 70 : B3DTuple(rTuple) 71 {} 72 73 /** *=operator to allow usage from B3DVector, too 74 */ operator *=(const B3DVector & rPnt)75 B3DVector& operator*=( const B3DVector& rPnt ) 76 { 77 mfX *= rPnt.mfX; 78 mfY *= rPnt.mfY; 79 mfZ *= rPnt.mfZ; 80 return *this; 81 } 82 83 /** *=operator to allow usage from B3DVector, too 84 */ operator *=(double t)85 B3DVector& operator*=(double t) 86 { 87 mfX *= t; 88 mfY *= t; 89 mfZ *= t; 90 return *this; 91 } 92 93 /** assignment operator to allow assigning the results 94 of B3DTuple calculations 95 */ operator =(const::basegfx::B3DTuple & rVec)96 B3DVector& operator=( const ::basegfx::B3DTuple& rVec ) 97 { 98 mfX = rVec.getX(); 99 mfY = rVec.getY(); 100 mfZ = rVec.getZ(); 101 return *this; 102 } 103 104 /** Calculate the length of this 3D Vector 105 106 @return The Length of the 3D Vector 107 */ getLength() const108 double getLength() const 109 { 110 double fLen(scalar(*this)); 111 if((0.0 == fLen) || (1.0 == fLen)) 112 return fLen; 113 return sqrt(fLen); 114 } 115 116 /** Calculate the length in the XZ-Plane for this 3D Vector 117 118 @return The XZ-Plane Length of the 3D Vector 119 */ getXZLength() const120 double getXZLength() const 121 { 122 double fLen((mfX * mfX) + (mfZ * mfZ)); // #i73040# 123 if((0.0 == fLen) || (1.0 == fLen)) 124 return fLen; 125 return sqrt(fLen); 126 } 127 128 /** Calculate the length in the YZ-Plane for this 3D Vector 129 130 @return The YZ-Plane Length of the 3D Vector 131 */ getYZLength() const132 double getYZLength() const 133 { 134 double fLen((mfY * mfY) + (mfZ * mfZ)); 135 if((0.0 == fLen) || (1.0 == fLen)) 136 return fLen; 137 return sqrt(fLen); 138 } 139 140 /** Set the length of this 3D Vector 141 142 @param fLen 143 The to be achieved length of the 3D Vector 144 */ setLength(double fLen)145 B3DVector& setLength(double fLen) 146 { 147 double fLenNow(scalar(*this)); 148 149 if(!::basegfx::fTools::equalZero(fLenNow)) 150 { 151 const double fOne(1.0); 152 153 if(!::basegfx::fTools::equal(fOne, fLenNow)) 154 { 155 fLen /= sqrt(fLenNow); 156 } 157 158 mfX *= fLen; 159 mfY *= fLen; 160 mfZ *= fLen; 161 } 162 163 return *this; 164 } 165 166 /** Normalize this 3D Vector 167 168 The length of the 3D Vector is set to 1.0 169 */ 170 B3DVector& normalize(); 171 172 /** get a 3D Vector which is perpendicular to this and a given 3D Vector 173 174 @attention This only works if this and the given 3D Vector are 175 both normalized. 176 177 @param rNormalizedVec 178 A normalized 3D Vector. 179 180 @return 181 A 3D Vector perpendicular to this and the given one 182 */ 183 B3DVector getPerpendicular(const B3DVector& rNormalizedVec) const; 184 185 /** Calculate the Scalar product 186 187 This method calculates the Scalar product between this 188 and the given 3D Vector. 189 190 @param rVec 191 A second 3D Vector. 192 193 @return 194 The Scalar Product of two 3D Vectors 195 */ scalar(const B3DVector & rVec) const196 double scalar(const B3DVector& rVec) const 197 { 198 return ((mfX * rVec.mfX) + (mfY * rVec.mfY) + (mfZ * rVec.mfZ)); 199 } 200 201 /** Transform vector by given transformation matrix. 202 203 Since this is a vector, translational components of the 204 matrix are disregarded. 205 */ 206 B3DVector& operator*=( const B3DHomMatrix& rMat ); 207 getEmptyVector()208 static const B3DVector& getEmptyVector() 209 { 210 return static_cast<const B3DVector&>( ::basegfx::B3DTuple::getEmptyTuple() ); 211 } 212 }; 213 214 // external operators 215 216 217 /** Test two vectors which need not to be normalized for parallelism 218 219 @param rVecA 220 The first 3D Vector 221 222 @param rVecB 223 The second 3D Vector 224 225 @return 226 bool if the two values are parallel. Also true if 227 one of the vectors is empty. 228 */ 229 BASEGFX_DLLPUBLIC bool areParallel( const B3DVector& rVecA, const B3DVector& rVecB ); 230 231 /** Transform vector by given transformation matrix. 232 233 Since this is a vector, translational components of the 234 matrix are disregarded. 235 */ 236 BASEGFX_DLLPUBLIC B3DVector operator*( const B3DHomMatrix& rMat, const B3DVector& rVec ); 237 238 /** Calculate the Cross Product of two 3D Vectors 239 240 @param rVecA 241 A first 3D Vector. 242 243 @param rVecB 244 A second 3D Vector. 245 246 @return 247 The Cross Product of both 3D Vectors 248 */ cross(const B3DVector & rVecA,const B3DVector & rVecB)249 inline B3DVector cross(const B3DVector& rVecA, const B3DVector& rVecB) 250 { 251 B3DVector aVec( 252 rVecA.getY() * rVecB.getZ() - rVecA.getZ() * rVecB.getY(), 253 rVecA.getZ() * rVecB.getX() - rVecA.getX() * rVecB.getZ(), 254 rVecA.getX() * rVecB.getY() - rVecA.getY() * rVecB.getX()); 255 return aVec; 256 } 257 } // end of namespace basegfx 258 259 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 260