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