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