xref: /AOO41X/main/basegfx/inc/basegfx/tuple/b3dtuple.hxx (revision d3e0dd8eb215533c15e891ee35bd141abe9397ee)
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 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     B3ITuple fround(const B3DTuple& rTup);
440 } // end of namespace basegfx
441 
442 #endif /* _BGFX_TUPLE_B3DTUPLE_HXX */
443