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