109dbbe93SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
309dbbe93SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
409dbbe93SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
509dbbe93SAndrew Rist  * distributed with this work for additional information
609dbbe93SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
709dbbe93SAndrew Rist  * to you under the Apache License, Version 2.0 (the
809dbbe93SAndrew Rist  * "License"); you may not use this file except in compliance
909dbbe93SAndrew Rist  * with the License.  You may obtain a copy of the License at
1009dbbe93SAndrew Rist  *
1109dbbe93SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1209dbbe93SAndrew Rist  *
1309dbbe93SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1409dbbe93SAndrew Rist  * software distributed under the License is distributed on an
1509dbbe93SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1609dbbe93SAndrew Rist  * KIND, either express or implied.  See the License for the
1709dbbe93SAndrew Rist  * specific language governing permissions and limitations
1809dbbe93SAndrew Rist  * under the License.
1909dbbe93SAndrew Rist  *
2009dbbe93SAndrew Rist  *************************************************************/
2109dbbe93SAndrew Rist 
2209dbbe93SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_basegfx.hxx"
26cdf0e10cSrcweir #include <basegfx/vector/b2dvector.hxx>
27cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
28cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir namespace basegfx
31cdf0e10cSrcweir {
normalize()32cdf0e10cSrcweir 	B2DVector& B2DVector::normalize()
33cdf0e10cSrcweir 	{
34cdf0e10cSrcweir 		double fLen(scalar(*this));
35cdf0e10cSrcweir 
36cdf0e10cSrcweir 		if(fTools::equalZero(fLen))
37cdf0e10cSrcweir 		{
38cdf0e10cSrcweir 			mfX = 0.0;
39cdf0e10cSrcweir 			mfY = 0.0;
40cdf0e10cSrcweir 		}
41cdf0e10cSrcweir 		else
42cdf0e10cSrcweir 		{
43cdf0e10cSrcweir 			const double fOne(1.0);
44cdf0e10cSrcweir 
45cdf0e10cSrcweir 			if(!fTools::equal(fOne, fLen))
46cdf0e10cSrcweir 			{
47cdf0e10cSrcweir 				fLen = sqrt(fLen);
48cdf0e10cSrcweir 
49cdf0e10cSrcweir 				if(!fTools::equalZero(fLen))
50cdf0e10cSrcweir 				{
51cdf0e10cSrcweir 					mfX /= fLen;
52cdf0e10cSrcweir 					mfY /= fLen;
53cdf0e10cSrcweir 				}
54cdf0e10cSrcweir 			}
55cdf0e10cSrcweir 		}
56cdf0e10cSrcweir 
57cdf0e10cSrcweir 		return *this;
58cdf0e10cSrcweir 	}
59cdf0e10cSrcweir 
operator =(const B2DTuple & rVec)60cdf0e10cSrcweir 	B2DVector& B2DVector::operator=( const B2DTuple& rVec )
61cdf0e10cSrcweir 	{
62cdf0e10cSrcweir 		mfX = rVec.getX();
63cdf0e10cSrcweir 		mfY = rVec.getY();
64cdf0e10cSrcweir 		return *this;
65cdf0e10cSrcweir 	}
66cdf0e10cSrcweir 
67cdf0e10cSrcweir 
getLength() const68cdf0e10cSrcweir 	double B2DVector::getLength() const
69cdf0e10cSrcweir 	{
70cdf0e10cSrcweir         if(fTools::equalZero(mfX))
71cdf0e10cSrcweir         {
72cdf0e10cSrcweir             return fabs(mfY);
73cdf0e10cSrcweir         }
74cdf0e10cSrcweir         else if(fTools::equalZero(mfY))
75cdf0e10cSrcweir         {
76cdf0e10cSrcweir             return fabs(mfX);
77cdf0e10cSrcweir         }
78cdf0e10cSrcweir 
79cdf0e10cSrcweir         return hypot( mfX, mfY );
80cdf0e10cSrcweir 	}
81cdf0e10cSrcweir 
scalar(const B2DVector & rVec) const82cdf0e10cSrcweir 	double B2DVector::scalar( const B2DVector& rVec ) const
83cdf0e10cSrcweir 	{
84cdf0e10cSrcweir 		return((mfX * rVec.mfX) + (mfY * rVec.mfY));
85cdf0e10cSrcweir 	}
86cdf0e10cSrcweir 
cross(const B2DVector & rVec) const87cdf0e10cSrcweir 	double B2DVector::cross( const B2DVector& rVec ) const
88cdf0e10cSrcweir 	{
89cdf0e10cSrcweir 		return(mfX * rVec.getY() - mfY * rVec.getX());
90cdf0e10cSrcweir 	}
91cdf0e10cSrcweir 
angle(const B2DVector & rVec) const92cdf0e10cSrcweir 	double B2DVector::angle( const B2DVector& rVec ) const
93cdf0e10cSrcweir 	{
94cdf0e10cSrcweir 		return atan2(mfX * rVec.getY() - mfY * rVec.getX(),
95cdf0e10cSrcweir 			mfX * rVec.getX() + mfY * rVec.getY());
96cdf0e10cSrcweir 	}
97cdf0e10cSrcweir 
getEmptyVector()98cdf0e10cSrcweir 	const B2DVector& B2DVector::getEmptyVector()
99cdf0e10cSrcweir 	{
100cdf0e10cSrcweir 		return (const B2DVector&) B2DTuple::getEmptyTuple();
101cdf0e10cSrcweir 	}
102cdf0e10cSrcweir 
operator *=(const B2DHomMatrix & rMat)103cdf0e10cSrcweir 	B2DVector& B2DVector::operator*=( const B2DHomMatrix& rMat )
104cdf0e10cSrcweir 	{
105cdf0e10cSrcweir 		const double fTempX( rMat.get(0,0)*mfX +
106cdf0e10cSrcweir 							rMat.get(0,1)*mfY );
107cdf0e10cSrcweir 		const double fTempY( rMat.get(1,0)*mfX +
108cdf0e10cSrcweir 							rMat.get(1,1)*mfY );
109cdf0e10cSrcweir 		mfX = fTempX;
110cdf0e10cSrcweir 		mfY = fTempY;
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 		return *this;
113cdf0e10cSrcweir 	}
114cdf0e10cSrcweir 
setLength(double fLen)115cdf0e10cSrcweir 	B2DVector& B2DVector::setLength(double fLen)
116cdf0e10cSrcweir 	{
117cdf0e10cSrcweir 		double fLenNow(scalar(*this));
118cdf0e10cSrcweir 
119cdf0e10cSrcweir 		if(!fTools::equalZero(fLenNow))
120cdf0e10cSrcweir 		{
121*1c346908SArmin Le Grand 			const double fOne(1.0);
122cdf0e10cSrcweir 
123cdf0e10cSrcweir 			if(!fTools::equal(fOne, fLenNow))
124cdf0e10cSrcweir 			{
125cdf0e10cSrcweir 				fLen /= sqrt(fLenNow);
126cdf0e10cSrcweir 			}
127cdf0e10cSrcweir 
128cdf0e10cSrcweir 			mfX *= fLen;
129cdf0e10cSrcweir 			mfY *= fLen;
130cdf0e10cSrcweir 		}
131cdf0e10cSrcweir 
132cdf0e10cSrcweir 		return *this;
133cdf0e10cSrcweir 	}
134cdf0e10cSrcweir 
isNormalized() const135cdf0e10cSrcweir 	bool B2DVector::isNormalized() const
136cdf0e10cSrcweir 	{
137cdf0e10cSrcweir 		const double fOne(1.0);
138cdf0e10cSrcweir 		const double fScalar(scalar(*this));
139cdf0e10cSrcweir 
140cdf0e10cSrcweir 		return fTools::equal(fOne, fScalar);
141cdf0e10cSrcweir 	}
142cdf0e10cSrcweir 
areParallel(const B2DVector & rVecA,const B2DVector & rVecB)143cdf0e10cSrcweir 	bool areParallel( const B2DVector& rVecA, const B2DVector& rVecB )
144cdf0e10cSrcweir 	{
145cdf0e10cSrcweir 		const double fValA(rVecA.getX() * rVecB.getY());
146cdf0e10cSrcweir 		const double fValB(rVecA.getY() * rVecB.getX());
147cdf0e10cSrcweir 
148cdf0e10cSrcweir 		return fTools::equal(fValA, fValB);
149cdf0e10cSrcweir 	}
150cdf0e10cSrcweir 
getOrientation(const B2DVector & rVecA,const B2DVector & rVecB)151cdf0e10cSrcweir 	B2VectorOrientation getOrientation( const B2DVector& rVecA, const B2DVector& rVecB )
152cdf0e10cSrcweir 	{
153cdf0e10cSrcweir 		double fVal(rVecA.getX() * rVecB.getY() - rVecA.getY() * rVecB.getX());
154cdf0e10cSrcweir 
155cdf0e10cSrcweir 		if(fTools::equalZero(fVal))
156cdf0e10cSrcweir 		{
157cdf0e10cSrcweir 			return ORIENTATION_NEUTRAL;
158cdf0e10cSrcweir 		}
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 		if(fVal > 0.0)
161cdf0e10cSrcweir 		{
162cdf0e10cSrcweir 			return ORIENTATION_POSITIVE;
163cdf0e10cSrcweir 		}
164cdf0e10cSrcweir 		else
165cdf0e10cSrcweir 		{
166cdf0e10cSrcweir 			return ORIENTATION_NEGATIVE;
167cdf0e10cSrcweir 		}
168cdf0e10cSrcweir 	}
169cdf0e10cSrcweir 
getPerpendicular(const B2DVector & rNormalizedVec)170cdf0e10cSrcweir 	B2DVector getPerpendicular( const B2DVector& rNormalizedVec )
171cdf0e10cSrcweir 	{
172cdf0e10cSrcweir 		B2DVector aPerpendicular(-rNormalizedVec.getY(), rNormalizedVec.getX());
173cdf0e10cSrcweir 		return aPerpendicular;
174cdf0e10cSrcweir 	}
175cdf0e10cSrcweir 
getNormalizedPerpendicular(const B2DVector & rVec)176cdf0e10cSrcweir 	B2DVector getNormalizedPerpendicular( const B2DVector& rVec )
177cdf0e10cSrcweir 	{
178cdf0e10cSrcweir 		B2DVector aPerpendicular(rVec);
179cdf0e10cSrcweir 		aPerpendicular.normalize();
180cdf0e10cSrcweir 		const double aTemp(-aPerpendicular.getY());
181cdf0e10cSrcweir 		aPerpendicular.setY(aPerpendicular.getX());
182cdf0e10cSrcweir 		aPerpendicular.setX(aTemp);
183cdf0e10cSrcweir 		return aPerpendicular;
184cdf0e10cSrcweir 	}
185cdf0e10cSrcweir 
operator *(const B2DHomMatrix & rMat,const B2DVector & rVec)186cdf0e10cSrcweir 	B2DVector operator*( const B2DHomMatrix& rMat, const B2DVector& rVec )
187cdf0e10cSrcweir 	{
188cdf0e10cSrcweir 		B2DVector aRes( rVec );
189cdf0e10cSrcweir 		return aRes*=rMat;
190cdf0e10cSrcweir 	}
191cdf0e10cSrcweir 
getContinuity(const B2DVector & rBackVector,const B2DVector & rForwardVector)192cdf0e10cSrcweir 	B2VectorContinuity getContinuity(const B2DVector& rBackVector, const B2DVector& rForwardVector )
193cdf0e10cSrcweir 	{
194cdf0e10cSrcweir 		if(rBackVector.equalZero() || rForwardVector.equalZero())
195cdf0e10cSrcweir 		{
196cdf0e10cSrcweir 			return CONTINUITY_NONE;
197cdf0e10cSrcweir 		}
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 		if(fTools::equal(rBackVector.getX(), -rForwardVector.getX()) && fTools::equal(rBackVector.getY(), -rForwardVector.getY()))
200cdf0e10cSrcweir 		{
201cdf0e10cSrcweir 			// same direction and same length -> C2
202cdf0e10cSrcweir 			return CONTINUITY_C2;
203cdf0e10cSrcweir 		}
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 		if(areParallel(rBackVector, rForwardVector) && rBackVector.scalar(rForwardVector) < 0.0)
206cdf0e10cSrcweir 		{
207cdf0e10cSrcweir 			// parallel and opposite direction -> C1
208cdf0e10cSrcweir 			return CONTINUITY_C1;
209cdf0e10cSrcweir 		}
210cdf0e10cSrcweir 
211cdf0e10cSrcweir 		return CONTINUITY_NONE;
212cdf0e10cSrcweir 	}
213cdf0e10cSrcweir } // end of namespace basegfx
214cdf0e10cSrcweir 
215cdf0e10cSrcweir // eof
216