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