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_B3DTUPLE_HXX 25 #define _BGFX_TUPLE_B3DTUPLE_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 B3ITuple; 37 38 /** Base class for all Points/Vectors with three 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 three double values 45 */ 46 class BASEGFX_DLLPUBLIC B3DTuple 47 { 48 protected: 49 double mfX; 50 double mfY; 51 double mfZ; 52 53 public: 54 /** Create a 3D Tuple 55 56 The tuple is initialized to (0.0, 0.0, 0.0) 57 */ B3DTuple()58 B3DTuple() 59 : mfX(0.0), 60 mfY(0.0), 61 mfZ(0.0) 62 {} 63 64 /** Create a 3D Tuple 65 66 @param fX 67 This parameter is used to initialize the X-coordinate 68 of the 3D Tuple. 69 70 @param fY 71 This parameter is used to initialize the Y-coordinate 72 of the 3D Tuple. 73 74 @param fZ 75 This parameter is used to initialize the Z-coordinate 76 of the 3D Tuple. 77 */ B3DTuple(double fX,double fY,double fZ)78 B3DTuple(double fX, double fY, double fZ) 79 : mfX(fX), 80 mfY(fY), 81 mfZ(fZ) 82 {} 83 84 /** Create a copy of a 3D Tuple 85 86 @param rTup 87 The 3D Tuple which will be copied. 88 */ B3DTuple(const B3DTuple & rTup)89 B3DTuple(const B3DTuple& rTup) 90 : mfX( rTup.mfX ), 91 mfY( rTup.mfY ), 92 mfZ( rTup.mfZ ) 93 {} 94 95 /** Create a copy of a 3D integer Tuple 96 97 @param rTup 98 The 3D Tuple which will be copied. 99 */ 100 explicit B3DTuple(const B3ITuple& rTup); 101 ~B3DTuple()102 ~B3DTuple() 103 {} 104 105 /// get X-Coordinate of 3D Tuple getX() const106 double getX() const 107 { 108 return mfX; 109 } 110 111 /// get Y-Coordinate of 3D Tuple getY() const112 double getY() const 113 { 114 return mfY; 115 } 116 117 /// get Z-Coordinate of 3D Tuple getZ() const118 double getZ() const 119 { 120 return mfZ; 121 } 122 123 /// set X-Coordinate of 3D Tuple setX(double fX)124 void setX(double fX) 125 { 126 mfX = fX; 127 } 128 129 /// set Y-Coordinate of 3D Tuple setY(double fY)130 void setY(double fY) 131 { 132 mfY = fY; 133 } 134 135 /// set Z-Coordinate of 3D Tuple setZ(double fZ)136 void setZ(double fZ) 137 { 138 mfZ = fZ; 139 } 140 141 /// Array-access to 3D Tuple operator [](int nPos) const142 const double& operator[] (int nPos) const 143 { 144 // Here, normally two if(...)'s should be used. In the assumption that 145 // both double members can be accessed as an array a shortcut is used here. 146 // if(0 == nPos) return mfX; if(1 == nPos) return mfY; return mfZ; 147 return *((&mfX) + nPos); 148 } 149 150 /// Array-access to 3D Tuple operator [](int nPos)151 double& operator[] (int nPos) 152 { 153 // Here, normally two if(...)'s should be used. In the assumption that 154 // both double members can be accessed as an array a shortcut is used here. 155 // if(0 == nPos) return mfX; if(1 == nPos) return mfY; return mfZ; 156 return *((&mfX) + nPos); 157 } 158 159 // comparators with tolerance 160 ////////////////////////////////////////////////////////////////////// 161 equalZero() const162 bool equalZero() const 163 { 164 return (this == &getEmptyTuple() || 165 (::basegfx::fTools::equalZero(mfX) 166 && ::basegfx::fTools::equalZero(mfY) 167 && ::basegfx::fTools::equalZero(mfZ))); 168 } 169 equalZero(const double & rfSmallValue) const170 bool equalZero(const double& rfSmallValue) const 171 { 172 return (this == &getEmptyTuple() || 173 (::basegfx::fTools::equalZero(mfX, rfSmallValue) 174 && ::basegfx::fTools::equalZero(mfY, rfSmallValue) 175 && ::basegfx::fTools::equalZero(mfZ, rfSmallValue))); 176 } 177 equal(const B3DTuple & rTup) const178 bool equal(const B3DTuple& rTup) const 179 { 180 return ( 181 this == &rTup || 182 (::basegfx::fTools::equal(mfX, rTup.mfX) && 183 ::basegfx::fTools::equal(mfY, rTup.mfY) && 184 ::basegfx::fTools::equal(mfZ, rTup.mfZ))); 185 } 186 equal(const B3DTuple & rTup,const double & rfSmallValue) const187 bool equal(const B3DTuple& rTup, const double& rfSmallValue) const 188 { 189 return ( 190 this == &rTup || 191 (::basegfx::fTools::equal(mfX, rTup.mfX, rfSmallValue) && 192 ::basegfx::fTools::equal(mfY, rTup.mfY, rfSmallValue) && 193 ::basegfx::fTools::equal(mfZ, rTup.mfZ, rfSmallValue))); 194 } 195 196 // operators 197 ////////////////////////////////////////////////////////////////////// 198 operator +=(const B3DTuple & rTup)199 B3DTuple& operator+=( const B3DTuple& rTup ) 200 { 201 mfX += rTup.mfX; 202 mfY += rTup.mfY; 203 mfZ += rTup.mfZ; 204 return *this; 205 } 206 operator -=(const B3DTuple & rTup)207 B3DTuple& operator-=( const B3DTuple& rTup ) 208 { 209 mfX -= rTup.mfX; 210 mfY -= rTup.mfY; 211 mfZ -= rTup.mfZ; 212 return *this; 213 } 214 operator /=(const B3DTuple & rTup)215 B3DTuple& operator/=( const B3DTuple& rTup ) 216 { 217 mfX /= rTup.mfX; 218 mfY /= rTup.mfY; 219 mfZ /= rTup.mfZ; 220 return *this; 221 } 222 operator *=(const B3DTuple & rTup)223 B3DTuple& operator*=( const B3DTuple& rTup ) 224 { 225 mfX *= rTup.mfX; 226 mfY *= rTup.mfY; 227 mfZ *= rTup.mfZ; 228 return *this; 229 } 230 operator *=(double t)231 B3DTuple& operator*=(double t) 232 { 233 mfX *= t; 234 mfY *= t; 235 mfZ *= t; 236 return *this; 237 } 238 operator /=(double t)239 B3DTuple& operator/=(double t) 240 { 241 const double fVal(1.0 / t); 242 mfX *= fVal; 243 mfY *= fVal; 244 mfZ *= fVal; 245 return *this; 246 } 247 operator -(void) const248 B3DTuple operator-(void) const 249 { 250 return B3DTuple(-mfX, -mfY, -mfZ); 251 } 252 operator ==(const B3DTuple & rTup) const253 bool operator==( const B3DTuple& rTup ) const 254 { 255 return mfX == rTup.mfX && mfY == rTup.mfY && mfZ == rTup.mfZ; 256 } 257 operator !=(const B3DTuple & rTup) const258 bool operator!=( const B3DTuple& rTup ) const 259 { 260 return mfX != rTup.mfX || mfY != rTup.mfY || mfZ != rTup.mfZ; 261 } 262 operator =(const B3DTuple & rTup)263 B3DTuple& operator=( const B3DTuple& rTup ) 264 { 265 mfX = rTup.mfX; 266 mfY = rTup.mfY; 267 mfZ = rTup.mfZ; 268 return *this; 269 } 270 correctValues(const double fCompareValue=0.0)271 void correctValues(const double fCompareValue = 0.0) 272 { 273 if(0.0 == fCompareValue) 274 { 275 if(::basegfx::fTools::equalZero(mfX)) 276 { 277 mfX = 0.0; 278 } 279 280 if(::basegfx::fTools::equalZero(mfY)) 281 { 282 mfY = 0.0; 283 } 284 285 if(::basegfx::fTools::equalZero(mfZ)) 286 { 287 mfZ = 0.0; 288 } 289 } 290 else 291 { 292 if(::basegfx::fTools::equal(mfX, fCompareValue)) 293 { 294 mfX = fCompareValue; 295 } 296 297 if(::basegfx::fTools::equal(mfY, fCompareValue)) 298 { 299 mfY = fCompareValue; 300 } 301 302 if(::basegfx::fTools::equal(mfZ, fCompareValue)) 303 { 304 mfZ = fCompareValue; 305 } 306 } 307 } 308 309 static const B3DTuple& getEmptyTuple(); 310 }; 311 312 // external operators 313 ////////////////////////////////////////////////////////////////////////// 314 minimum(const B3DTuple & rTupA,const B3DTuple & rTupB)315 inline B3DTuple minimum(const B3DTuple& rTupA, const B3DTuple& rTupB) 316 { 317 return B3DTuple( 318 std::min(rTupB.getX(), rTupA.getX()), 319 std::min(rTupB.getY(), rTupA.getY()), 320 std::min(rTupB.getZ(), rTupA.getZ())); 321 } 322 maximum(const B3DTuple & rTupA,const B3DTuple & rTupB)323 inline B3DTuple maximum(const B3DTuple& rTupA, const B3DTuple& rTupB) 324 { 325 return B3DTuple( 326 std::max(rTupB.getX(), rTupA.getX()), 327 std::max(rTupB.getY(), rTupA.getY()), 328 std::max(rTupB.getZ(), rTupA.getZ())); 329 } 330 absolute(const B3DTuple & rTup)331 inline B3DTuple absolute(const B3DTuple& rTup) 332 { 333 B3DTuple aAbs( 334 fabs(rTup.getX()), 335 fabs(rTup.getY()), 336 fabs(rTup.getZ())); 337 return aAbs; 338 } 339 interpolate(const B3DTuple & rOld1,const B3DTuple & rOld2,double t)340 inline B3DTuple interpolate(const B3DTuple& rOld1, const B3DTuple& rOld2, double t) 341 { 342 if(rOld1 == rOld2) 343 { 344 return rOld1; 345 } 346 else if(0.0 >= t) 347 { 348 return rOld1; 349 } 350 else if(1.0 <= t) 351 { 352 return rOld2; 353 } 354 else 355 { 356 return B3DTuple( 357 ((rOld2.getX() - rOld1.getX()) * t) + rOld1.getX(), 358 ((rOld2.getY() - rOld1.getY()) * t) + rOld1.getY(), 359 ((rOld2.getZ() - rOld1.getZ()) * t) + rOld1.getZ()); 360 } 361 } 362 average(const B3DTuple & rOld1,const B3DTuple & rOld2)363 inline B3DTuple average(const B3DTuple& rOld1, const B3DTuple& rOld2) 364 { 365 return B3DTuple( 366 rOld1.getX() == rOld2.getX() ? rOld1.getX() : (rOld1.getX() + rOld2.getX()) * 0.5, 367 rOld1.getY() == rOld2.getY() ? rOld1.getY() : (rOld1.getY() + rOld2.getY()) * 0.5, 368 rOld1.getZ() == rOld2.getZ() ? rOld1.getZ() : (rOld1.getZ() + rOld2.getZ()) * 0.5); 369 } 370 average(const B3DTuple & rOld1,const B3DTuple & rOld2,const B3DTuple & rOld3)371 inline B3DTuple average(const B3DTuple& rOld1, const B3DTuple& rOld2, const B3DTuple& rOld3) 372 { 373 return B3DTuple( 374 (rOld1.getX() == rOld2.getX() && rOld2.getX() == rOld3.getX()) ? rOld1.getX() : (rOld1.getX() + rOld2.getX() + rOld3.getX()) * (1.0 / 3.0), 375 (rOld1.getY() == rOld2.getY() && rOld2.getY() == rOld3.getY()) ? rOld1.getY() : (rOld1.getY() + rOld2.getY() + rOld3.getY()) * (1.0 / 3.0), 376 (rOld1.getZ() == rOld2.getZ() && rOld2.getZ() == rOld3.getZ()) ? rOld1.getZ() : (rOld1.getZ() + rOld2.getZ() + rOld3.getZ()) * (1.0 / 3.0)); 377 } 378 operator +(const B3DTuple & rTupA,const B3DTuple & rTupB)379 inline B3DTuple operator+(const B3DTuple& rTupA, const B3DTuple& rTupB) 380 { 381 B3DTuple aSum(rTupA); 382 aSum += rTupB; 383 return aSum; 384 } 385 operator -(const B3DTuple & rTupA,const B3DTuple & rTupB)386 inline B3DTuple operator-(const B3DTuple& rTupA, const B3DTuple& rTupB) 387 { 388 B3DTuple aSub(rTupA); 389 aSub -= rTupB; 390 return aSub; 391 } 392 operator /(const B3DTuple & rTupA,const B3DTuple & rTupB)393 inline B3DTuple operator/(const B3DTuple& rTupA, const B3DTuple& rTupB) 394 { 395 B3DTuple aDiv(rTupA); 396 aDiv /= rTupB; 397 return aDiv; 398 } 399 operator *(const B3DTuple & rTupA,const B3DTuple & rTupB)400 inline B3DTuple operator*(const B3DTuple& rTupA, const B3DTuple& rTupB) 401 { 402 B3DTuple aMul(rTupA); 403 aMul *= rTupB; 404 return aMul; 405 } 406 operator *(const B3DTuple & rTup,double t)407 inline B3DTuple operator*(const B3DTuple& rTup, double t) 408 { 409 B3DTuple aNew(rTup); 410 aNew *= t; 411 return aNew; 412 } 413 operator *(double t,const B3DTuple & rTup)414 inline B3DTuple operator*(double t, const B3DTuple& rTup) 415 { 416 B3DTuple aNew(rTup); 417 aNew *= t; 418 return aNew; 419 } 420 operator /(const B3DTuple & rTup,double t)421 inline B3DTuple operator/(const B3DTuple& rTup, double t) 422 { 423 B3DTuple aNew(rTup); 424 aNew /= t; 425 return aNew; 426 } 427 operator /(double t,const B3DTuple & rTup)428 inline B3DTuple operator/(double t, const B3DTuple& rTup) 429 { 430 B3DTuple aNew(rTup); 431 aNew /= t; 432 return aNew; 433 } 434 435 /** Round double to nearest integer for 3D tuple 436 437 @return the nearest integer for this tuple 438 */ 439 BASEGFX_DLLPUBLIC B3ITuple fround(const B3DTuple& rTup); 440 } // end of namespace basegfx 441 442 #endif /* _BGFX_TUPLE_B3DTUPLE_HXX */ 443