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 #ifndef _BGFX_TUPLE_B2DTUPLE_HXX
25 #define _BGFX_TUPLE_B2DTUPLE_HXX
26 
27 #include <sal/types.h>
28 #include <basegfx/numeric/ftools.hxx>
29 #undef min
30 #undef max
31 #include <algorithm>
32 
33 namespace basegfx
34 {
35 	// predeclarations
36 	class B2ITuple;
37 
38 	/** Base class for all Points/Vectors with two double values
39 
40 		This class provides all methods common to Point
41 		avd Vector classes which are derived from here.
42 
43 		@derive Use this class to implement Points or Vectors
44 		which are based on two double values
45 	*/
46 	class B2DTuple
47 	{
48 	protected:
49 		double										mfX;
50 		double										mfY;
51 
52 	public:
53 		/**	Create a 2D Tuple
54 
55         	The tuple is initialized to (0.0, 0.0)
56 		*/
B2DTuple()57 		B2DTuple()
58 		:	mfX(0.0),
59 			mfY(0.0)
60 		{}
61 
62 		/**	Create a 2D Tuple
63 
64 			@param fX
65 			This parameter is used to initialize the X-coordinate
66 			of the 2D Tuple.
67 
68 			@param fY
69 			This parameter is used to initialize the Y-coordinate
70 			of the 2D Tuple.
71 		*/
B2DTuple(double fX,double fY)72 		B2DTuple(double fX, double fY)
73 		:	mfX( fX ),
74 			mfY( fY )
75 		{}
76 
77 		/**	Create a copy of a 2D Tuple
78 
79 			@param rTup
80 			The 2D Tuple which will be copied.
81 		*/
B2DTuple(const B2DTuple & rTup)82 		B2DTuple(const B2DTuple& rTup)
83 		:	mfX( rTup.mfX ),
84 			mfY( rTup.mfY )
85 		{}
86 
87 		/**	Create a copy of a 2D integer Tuple
88 
89 			@param rTup
90 			The 2D Tuple which will be copied.
91 		*/
92 		BASEGFX_DLLPUBLIC explicit B2DTuple(const B2ITuple& rTup);
93 
~B2DTuple()94 		~B2DTuple()
95 		{}
96 
97 		/// Get X-Coordinate of 2D Tuple
getX() const98 		double getX() const
99 		{
100 			return mfX;
101 		}
102 
103 		/// Get Y-Coordinate of 2D Tuple
getY() const104 		double getY() const
105 		{
106 			return mfY;
107 		}
108 
109 		/// Set X-Coordinate of 2D Tuple
setX(double fX)110 		void setX(double fX)
111 		{
112 			mfX = fX;
113 		}
114 
115 		/// Set Y-Coordinate of 2D Tuple
setY(double fY)116 		void setY(double fY)
117 		{
118 			mfY = fY;
119 		}
120 
121 		/// Array-access to 2D Tuple
operator [](int nPos) const122 		const double& operator[] (int nPos) const
123 		{
124 			// Here, normally one if(...) should be used. In the assumption that
125 			// both double members can be accessed as an array a shortcut is used here.
126 			// if(0 == nPos) return mfX; return mfY;
127 			return *((&mfX) + nPos);
128 		}
129 
130 		/// Array-access to 2D Tuple
operator [](int nPos)131 		double& operator[] (int nPos)
132 		{
133 			// Here, normally one if(...) should be used. In the assumption that
134 			// both double members can be accessed as an array a shortcut is used here.
135 			// if(0 == nPos) return mfX; return mfY;
136 			return *((&mfX) + nPos);
137 		}
138 
139 		// comparators with tolerance
140 		//////////////////////////////////////////////////////////////////////
141 
equalZero() const142 		bool equalZero() const
143 		{
144 			return (this == &getEmptyTuple() ||
145 					(fTools::equalZero(mfX) && fTools::equalZero(mfY)));
146 		}
147 
equalZero(const double & rfSmallValue) const148 		bool equalZero(const double& rfSmallValue) const
149 		{
150 			return (this == &getEmptyTuple() ||
151 					(fTools::equalZero(mfX, rfSmallValue) && fTools::equalZero(mfY, rfSmallValue)));
152 		}
153 
equal(const B2DTuple & rTup) const154 		bool equal(const B2DTuple& rTup) const
155 		{
156 			return (
157 				this == &rTup ||
158 				(fTools::equal(mfX, rTup.mfX) &&
159 				fTools::equal(mfY, rTup.mfY)));
160 		}
161 
equal(const B2DTuple & rTup,const double & rfSmallValue) const162 		bool equal(const B2DTuple& rTup, const double& rfSmallValue) const
163 		{
164 			return (
165 				this == &rTup ||
166 				(fTools::equal(mfX, rTup.mfX, rfSmallValue) &&
167 				fTools::equal(mfY, rTup.mfY, rfSmallValue)));
168 		}
169 
170 		// operators
171 		//////////////////////////////////////////////////////////////////////
172 
operator +=(const B2DTuple & rTup)173 		B2DTuple& operator+=( const B2DTuple& rTup )
174 		{
175 			mfX += rTup.mfX;
176 			mfY += rTup.mfY;
177 			return *this;
178 		}
179 
operator -=(const B2DTuple & rTup)180 		B2DTuple& operator-=( const B2DTuple& rTup )
181 		{
182 			mfX -= rTup.mfX;
183 			mfY -= rTup.mfY;
184 			return *this;
185 		}
186 
operator /=(const B2DTuple & rTup)187 		B2DTuple& operator/=( const B2DTuple& rTup )
188 		{
189 			mfX /= rTup.mfX;
190 			mfY /= rTup.mfY;
191 			return *this;
192 		}
193 
operator *=(const B2DTuple & rTup)194 		B2DTuple& operator*=( const B2DTuple& rTup )
195 		{
196 			mfX *= rTup.mfX;
197 			mfY *= rTup.mfY;
198 			return *this;
199 		}
200 
operator *=(double t)201 		B2DTuple& operator*=(double t)
202 		{
203 			mfX *= t;
204 			mfY *= t;
205 			return *this;
206 		}
207 
operator /=(double t)208 		B2DTuple& operator/=(double t)
209 		{
210 			const double fVal(1.0 / t);
211 			mfX *= fVal;
212 			mfY *= fVal;
213 			return *this;
214 		}
215 
operator -(void) const216 		B2DTuple operator-(void) const
217 		{
218 			return B2DTuple(-mfX, -mfY);
219 		}
220 
operator ==(const B2DTuple & rTup) const221 		bool operator==( const B2DTuple& rTup ) const
222 		{
223 			return mfX == rTup.mfX && mfY == rTup.mfY;
224 		}
225 
operator !=(const B2DTuple & rTup) const226 		bool operator!=( const B2DTuple& rTup ) const
227 		{
228 			return mfX != rTup.mfX || mfY != rTup.mfY;
229 		}
230 
operator =(const B2DTuple & rTup)231 		B2DTuple& operator=( const B2DTuple& rTup )
232 		{
233 			mfX = rTup.mfX;
234 			mfY = rTup.mfY;
235 			return *this;
236 		}
237 
238 		BASEGFX_DLLPUBLIC void correctValues(const double fCompareValue = 0.0);
239 
240 		BASEGFX_DLLPUBLIC static const B2DTuple& getEmptyTuple();
241 	};
242 
243 	// external operators
244 	//////////////////////////////////////////////////////////////////////////
245 
minimum(const B2DTuple & rTupA,const B2DTuple & rTupB)246 	inline B2DTuple minimum(const B2DTuple& rTupA, const B2DTuple& rTupB)
247 	{
248         return B2DTuple(
249             std::min(rTupB.getX(), rTupA.getX()),
250             std::min(rTupB.getY(), rTupA.getY()));
251 	}
252 
maximum(const B2DTuple & rTupA,const B2DTuple & rTupB)253 	inline B2DTuple maximum(const B2DTuple& rTupA, const B2DTuple& rTupB)
254 	{
255         return B2DTuple(
256             std::max(rTupB.getX(), rTupA.getX()),
257             std::max(rTupB.getY(), rTupA.getY()));
258 	}
259 
absolute(const B2DTuple & rTup)260 	inline B2DTuple absolute(const B2DTuple& rTup)
261 	{
262 		B2DTuple aAbs(
263             fabs(rTup.getX()),
264             fabs(rTup.getY()));
265 		return aAbs;
266 	}
267 
interpolate(const B2DTuple & rOld1,const B2DTuple & rOld2,double t)268 	inline B2DTuple interpolate(const B2DTuple& rOld1, const B2DTuple& rOld2, double t)
269 	{
270         if(rOld1 == rOld2)
271         {
272             return rOld1;
273         }
274         else if(0.0 >= t)
275         {
276             return rOld1;
277         }
278         else if(1.0 <= t)
279         {
280             return rOld2;
281         }
282         else
283         {
284             return B2DTuple(
285 			    ((rOld2.getX() - rOld1.getX()) * t) + rOld1.getX(),
286 			    ((rOld2.getY() - rOld1.getY()) * t) + rOld1.getY());
287         }
288 	}
289 
average(const B2DTuple & rOld1,const B2DTuple & rOld2)290 	inline B2DTuple average(const B2DTuple& rOld1, const B2DTuple& rOld2)
291 	{
292         return B2DTuple(
293             rOld1.getX() == rOld2.getX() ? rOld1.getX() : (rOld1.getX() + rOld2.getX()) * 0.5,
294             rOld1.getY() == rOld2.getY() ? rOld1.getY() : (rOld1.getY() + rOld2.getY()) * 0.5);
295 	}
296 
average(const B2DTuple & rOld1,const B2DTuple & rOld2,const B2DTuple & rOld3)297 	inline B2DTuple average(const B2DTuple& rOld1, const B2DTuple& rOld2, const B2DTuple& rOld3)
298 	{
299         return B2DTuple(
300             (rOld1.getX() == rOld2.getX() && rOld2.getX() == rOld3.getX()) ? rOld1.getX() : (rOld1.getX() + rOld2.getX() + rOld3.getX()) * (1.0 / 3.0),
301             (rOld1.getY() == rOld2.getY() && rOld2.getY() == rOld3.getY()) ? rOld1.getY() : (rOld1.getY() + rOld2.getY() + rOld3.getY()) * (1.0 / 3.0));
302 	}
303 
operator +(const B2DTuple & rTupA,const B2DTuple & rTupB)304 	inline B2DTuple operator+(const B2DTuple& rTupA, const B2DTuple& rTupB)
305 	{
306 		B2DTuple aSum(rTupA);
307 		aSum += rTupB;
308 		return aSum;
309 	}
310 
operator -(const B2DTuple & rTupA,const B2DTuple & rTupB)311 	inline B2DTuple operator-(const B2DTuple& rTupA, const B2DTuple& rTupB)
312 	{
313 		B2DTuple aSub(rTupA);
314 		aSub -= rTupB;
315 		return aSub;
316 	}
317 
operator /(const B2DTuple & rTupA,const B2DTuple & rTupB)318 	inline B2DTuple operator/(const B2DTuple& rTupA, const B2DTuple& rTupB)
319 	{
320 		B2DTuple aDiv(rTupA);
321 		aDiv /= rTupB;
322 		return aDiv;
323 	}
324 
operator *(const B2DTuple & rTupA,const B2DTuple & rTupB)325 	inline B2DTuple operator*(const B2DTuple& rTupA, const B2DTuple& rTupB)
326 	{
327 		B2DTuple aMul(rTupA);
328 		aMul *= rTupB;
329 		return aMul;
330 	}
331 
operator *(const B2DTuple & rTup,double t)332 	inline B2DTuple operator*(const B2DTuple& rTup, double t)
333 	{
334 		B2DTuple aNew(rTup);
335 		aNew *= t;
336 		return aNew;
337 	}
338 
operator *(double t,const B2DTuple & rTup)339 	inline B2DTuple operator*(double t, const B2DTuple& rTup)
340 	{
341 		B2DTuple aNew(rTup);
342 		aNew *= t;
343 		return aNew;
344 	}
345 
operator /(const B2DTuple & rTup,double t)346 	inline B2DTuple operator/(const B2DTuple& rTup, double t)
347 	{
348 		B2DTuple aNew(rTup);
349 		aNew /= t;
350 		return aNew;
351 	}
352 
operator /(double t,const B2DTuple & rTup)353 	inline B2DTuple operator/(double t, const B2DTuple& rTup)
354 	{
355 		B2DTuple aNew(t, t);
356 		B2DTuple aTmp(rTup);
357 		aNew /= aTmp;
358 		return aNew;
359 	}
360 
361 	/** Round double to nearest integer for 2D tuple
362 
363 		@return the nearest integer for this tuple
364 	*/
365 	BASEGFX_DLLPUBLIC B2ITuple fround(const B2DTuple& rTup);
366 } // end of namespace basegfx
367 
368 #endif /* _BGFX_TUPLE_B2DTUPLE_HXX */
369