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