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 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_basegfx.hxx" 30 #include <basegfx/vector/b2dvector.hxx> 31 #include <basegfx/matrix/b2dhommatrix.hxx> 32 #include <basegfx/numeric/ftools.hxx> 33 34 namespace basegfx 35 { 36 B2DVector& B2DVector::normalize() 37 { 38 double fLen(scalar(*this)); 39 40 if(fTools::equalZero(fLen)) 41 { 42 mfX = 0.0; 43 mfY = 0.0; 44 } 45 else 46 { 47 const double fOne(1.0); 48 49 if(!fTools::equal(fOne, fLen)) 50 { 51 fLen = sqrt(fLen); 52 53 if(!fTools::equalZero(fLen)) 54 { 55 mfX /= fLen; 56 mfY /= fLen; 57 } 58 } 59 } 60 61 return *this; 62 } 63 64 B2DVector& B2DVector::operator=( const B2DTuple& rVec ) 65 { 66 mfX = rVec.getX(); 67 mfY = rVec.getY(); 68 return *this; 69 } 70 71 72 double B2DVector::getLength() const 73 { 74 if(fTools::equalZero(mfX)) 75 { 76 return fabs(mfY); 77 } 78 else if(fTools::equalZero(mfY)) 79 { 80 return fabs(mfX); 81 } 82 83 return hypot( mfX, mfY ); 84 } 85 86 double B2DVector::scalar( const B2DVector& rVec ) const 87 { 88 return((mfX * rVec.mfX) + (mfY * rVec.mfY)); 89 } 90 91 double B2DVector::cross( const B2DVector& rVec ) const 92 { 93 return(mfX * rVec.getY() - mfY * rVec.getX()); 94 } 95 96 double B2DVector::angle( const B2DVector& rVec ) const 97 { 98 return atan2(mfX * rVec.getY() - mfY * rVec.getX(), 99 mfX * rVec.getX() + mfY * rVec.getY()); 100 } 101 102 const B2DVector& B2DVector::getEmptyVector() 103 { 104 return (const B2DVector&) B2DTuple::getEmptyTuple(); 105 } 106 107 B2DVector& B2DVector::operator*=( const B2DHomMatrix& rMat ) 108 { 109 const double fTempX( rMat.get(0,0)*mfX + 110 rMat.get(0,1)*mfY ); 111 const double fTempY( rMat.get(1,0)*mfX + 112 rMat.get(1,1)*mfY ); 113 mfX = fTempX; 114 mfY = fTempY; 115 116 return *this; 117 } 118 119 B2DVector& B2DVector::setLength(double fLen) 120 { 121 double fLenNow(scalar(*this)); 122 123 if(!fTools::equalZero(fLenNow)) 124 { 125 const double fOne(10.0); 126 127 if(!fTools::equal(fOne, fLenNow)) 128 { 129 fLen /= sqrt(fLenNow); 130 } 131 132 mfX *= fLen; 133 mfY *= fLen; 134 } 135 136 return *this; 137 } 138 139 bool B2DVector::isNormalized() const 140 { 141 const double fOne(1.0); 142 const double fScalar(scalar(*this)); 143 144 return fTools::equal(fOne, fScalar); 145 } 146 147 bool areParallel( const B2DVector& rVecA, const B2DVector& rVecB ) 148 { 149 const double fValA(rVecA.getX() * rVecB.getY()); 150 const double fValB(rVecA.getY() * rVecB.getX()); 151 152 return fTools::equal(fValA, fValB); 153 } 154 155 B2VectorOrientation getOrientation( const B2DVector& rVecA, const B2DVector& rVecB ) 156 { 157 double fVal(rVecA.getX() * rVecB.getY() - rVecA.getY() * rVecB.getX()); 158 159 if(fTools::equalZero(fVal)) 160 { 161 return ORIENTATION_NEUTRAL; 162 } 163 164 if(fVal > 0.0) 165 { 166 return ORIENTATION_POSITIVE; 167 } 168 else 169 { 170 return ORIENTATION_NEGATIVE; 171 } 172 } 173 174 B2DVector getPerpendicular( const B2DVector& rNormalizedVec ) 175 { 176 B2DVector aPerpendicular(-rNormalizedVec.getY(), rNormalizedVec.getX()); 177 return aPerpendicular; 178 } 179 180 B2DVector getNormalizedPerpendicular( const B2DVector& rVec ) 181 { 182 B2DVector aPerpendicular(rVec); 183 aPerpendicular.normalize(); 184 const double aTemp(-aPerpendicular.getY()); 185 aPerpendicular.setY(aPerpendicular.getX()); 186 aPerpendicular.setX(aTemp); 187 return aPerpendicular; 188 } 189 190 B2DVector operator*( const B2DHomMatrix& rMat, const B2DVector& rVec ) 191 { 192 B2DVector aRes( rVec ); 193 return aRes*=rMat; 194 } 195 196 B2VectorContinuity getContinuity(const B2DVector& rBackVector, const B2DVector& rForwardVector ) 197 { 198 if(rBackVector.equalZero() || rForwardVector.equalZero()) 199 { 200 return CONTINUITY_NONE; 201 } 202 203 if(fTools::equal(rBackVector.getX(), -rForwardVector.getX()) && fTools::equal(rBackVector.getY(), -rForwardVector.getY())) 204 { 205 // same direction and same length -> C2 206 return CONTINUITY_C2; 207 } 208 209 if(areParallel(rBackVector, rForwardVector) && rBackVector.scalar(rForwardVector) < 0.0) 210 { 211 // parallel and opposite direction -> C1 212 return CONTINUITY_C1; 213 } 214 215 return CONTINUITY_NONE; 216 } 217 } // end of namespace basegfx 218 219 // eof 220