Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_BASEGFX_TUPLE_B3DTUPLE_HXX
21 : #define INCLUDED_BASEGFX_TUPLE_B3DTUPLE_HXX
22 :
23 : #include <sal/types.h>
24 : #include <basegfx/numeric/ftools.hxx>
25 : #include <algorithm>
26 : #include <basegfx/basegfxdllapi.h>
27 :
28 : namespace basegfx
29 : {
30 : // predeclarations
31 : class B3ITuple;
32 :
33 : /** Base class for all Points/Vectors with three double values
34 :
35 : This class provides all methods common to Point
36 : avd Vector classes which are derived from here.
37 :
38 : @derive Use this class to implement Points or Vectors
39 : which are based on three double values
40 : */
41 : class BASEGFX_DLLPUBLIC SAL_WARN_UNUSED B3DTuple
42 : {
43 : protected:
44 : double mfX;
45 : double mfY;
46 : double mfZ;
47 :
48 : public:
49 : /** Create a 3D Tuple
50 :
51 : The tuple is initialized to (0.0, 0.0, 0.0)
52 : */
53 0 : B3DTuple()
54 : : mfX(0.0),
55 : mfY(0.0),
56 0 : mfZ(0.0)
57 0 : {}
58 :
59 : /** Create a 3D Tuple
60 :
61 : @param fX
62 : This parameter is used to initialize the X-coordinate
63 : of the 3D Tuple.
64 :
65 : @param fY
66 : This parameter is used to initialize the Y-coordinate
67 : of the 3D Tuple.
68 :
69 : @param fZ
70 : This parameter is used to initialize the Z-coordinate
71 : of the 3D Tuple.
72 : */
73 0 : B3DTuple(double fX, double fY, double fZ)
74 : : mfX(fX),
75 : mfY(fY),
76 0 : mfZ(fZ)
77 0 : {}
78 :
79 : /** Create a copy of a 3D Tuple
80 :
81 : @param rTup
82 : The 3D Tuple which will be copied.
83 : */
84 0 : B3DTuple(const B3DTuple& rTup)
85 : : mfX( rTup.mfX ),
86 : mfY( rTup.mfY ),
87 0 : mfZ( rTup.mfZ )
88 0 : {}
89 :
90 0 : ~B3DTuple()
91 0 : {}
92 :
93 : /// get X-Coordinate of 3D Tuple
94 0 : double getX() const
95 : {
96 0 : return mfX;
97 : }
98 :
99 : /// get Y-Coordinate of 3D Tuple
100 0 : double getY() const
101 : {
102 0 : return mfY;
103 : }
104 :
105 : /// get Z-Coordinate of 3D Tuple
106 0 : double getZ() const
107 : {
108 0 : return mfZ;
109 : }
110 :
111 : /// set X-Coordinate of 3D Tuple
112 0 : void setX(double fX)
113 : {
114 0 : mfX = fX;
115 0 : }
116 :
117 : /// set Y-Coordinate of 3D Tuple
118 0 : void setY(double fY)
119 : {
120 0 : mfY = fY;
121 0 : }
122 :
123 : /// set Z-Coordinate of 3D Tuple
124 0 : void setZ(double fZ)
125 : {
126 0 : mfZ = fZ;
127 0 : }
128 :
129 : /// Array-access to 3D Tuple
130 : const double& operator[] (int nPos) const
131 : {
132 : // Here, normally two if(...)'s should be used. In the assumption that
133 : // both double members can be accessed as an array a shortcut is used here.
134 : // if(0 == nPos) return mfX; if(1 == nPos) return mfY; return mfZ;
135 : return *((&mfX) + nPos);
136 : }
137 :
138 : /// Array-access to 3D Tuple
139 0 : double& operator[] (int nPos)
140 : {
141 : // Here, normally two if(...)'s should be used. In the assumption that
142 : // both double members can be accessed as an array a shortcut is used here.
143 : // if(0 == nPos) return mfX; if(1 == nPos) return mfY; return mfZ;
144 0 : return *((&mfX) + nPos);
145 : }
146 :
147 : // comparators with tolerance
148 :
149 :
150 0 : bool equalZero() const
151 : {
152 0 : return (this == &getEmptyTuple() ||
153 0 : (::basegfx::fTools::equalZero(mfX)
154 0 : && ::basegfx::fTools::equalZero(mfY)
155 0 : && ::basegfx::fTools::equalZero(mfZ)));
156 : }
157 :
158 : bool equalZero(const double& rfSmallValue) const
159 : {
160 : return (this == &getEmptyTuple() ||
161 : (::basegfx::fTools::equalZero(mfX, rfSmallValue)
162 : && ::basegfx::fTools::equalZero(mfY, rfSmallValue)
163 : && ::basegfx::fTools::equalZero(mfZ, rfSmallValue)));
164 : }
165 :
166 0 : bool equal(const B3DTuple& rTup) const
167 : {
168 : return (
169 0 : this == &rTup ||
170 0 : (::basegfx::fTools::equal(mfX, rTup.mfX) &&
171 0 : ::basegfx::fTools::equal(mfY, rTup.mfY) &&
172 0 : ::basegfx::fTools::equal(mfZ, rTup.mfZ)));
173 : }
174 :
175 0 : bool equal(const B3DTuple& rTup, const double& rfSmallValue) const
176 : {
177 : return (
178 0 : this == &rTup ||
179 0 : (::basegfx::fTools::equal(mfX, rTup.mfX, rfSmallValue) &&
180 0 : ::basegfx::fTools::equal(mfY, rTup.mfY, rfSmallValue) &&
181 0 : ::basegfx::fTools::equal(mfZ, rTup.mfZ, rfSmallValue)));
182 : }
183 :
184 : // operators
185 :
186 :
187 0 : B3DTuple& operator+=( const B3DTuple& rTup )
188 : {
189 0 : mfX += rTup.mfX;
190 0 : mfY += rTup.mfY;
191 0 : mfZ += rTup.mfZ;
192 0 : return *this;
193 : }
194 :
195 0 : B3DTuple& operator-=( const B3DTuple& rTup )
196 : {
197 0 : mfX -= rTup.mfX;
198 0 : mfY -= rTup.mfY;
199 0 : mfZ -= rTup.mfZ;
200 0 : return *this;
201 : }
202 :
203 : B3DTuple& operator/=( const B3DTuple& rTup )
204 : {
205 : mfX /= rTup.mfX;
206 : mfY /= rTup.mfY;
207 : mfZ /= rTup.mfZ;
208 : return *this;
209 : }
210 :
211 0 : B3DTuple& operator*=( const B3DTuple& rTup )
212 : {
213 0 : mfX *= rTup.mfX;
214 0 : mfY *= rTup.mfY;
215 0 : mfZ *= rTup.mfZ;
216 0 : return *this;
217 : }
218 :
219 0 : B3DTuple& operator*=(double t)
220 : {
221 0 : mfX *= t;
222 0 : mfY *= t;
223 0 : mfZ *= t;
224 0 : return *this;
225 : }
226 :
227 0 : B3DTuple& operator/=(double t)
228 : {
229 0 : const double fVal(1.0 / t);
230 0 : mfX *= fVal;
231 0 : mfY *= fVal;
232 0 : mfZ *= fVal;
233 0 : return *this;
234 : }
235 :
236 0 : B3DTuple operator-(void) const
237 : {
238 0 : return B3DTuple(-mfX, -mfY, -mfZ);
239 : }
240 :
241 0 : bool operator==( const B3DTuple& rTup ) const
242 : {
243 0 : return mfX == rTup.mfX && mfY == rTup.mfY && mfZ == rTup.mfZ;
244 : }
245 :
246 0 : bool operator!=( const B3DTuple& rTup ) const
247 : {
248 0 : return mfX != rTup.mfX || mfY != rTup.mfY || mfZ != rTup.mfZ;
249 : }
250 :
251 0 : B3DTuple& operator=( const B3DTuple& rTup )
252 : {
253 0 : mfX = rTup.mfX;
254 0 : mfY = rTup.mfY;
255 0 : mfZ = rTup.mfZ;
256 0 : return *this;
257 : }
258 :
259 0 : void correctValues(const double fCompareValue = 0.0)
260 : {
261 0 : if(0.0 == fCompareValue)
262 : {
263 0 : if(::basegfx::fTools::equalZero(mfX))
264 : {
265 0 : mfX = 0.0;
266 : }
267 :
268 0 : if(::basegfx::fTools::equalZero(mfY))
269 : {
270 0 : mfY = 0.0;
271 : }
272 :
273 0 : if(::basegfx::fTools::equalZero(mfZ))
274 : {
275 0 : mfZ = 0.0;
276 : }
277 : }
278 : else
279 : {
280 0 : if(::basegfx::fTools::equal(mfX, fCompareValue))
281 : {
282 0 : mfX = fCompareValue;
283 : }
284 :
285 0 : if(::basegfx::fTools::equal(mfY, fCompareValue))
286 : {
287 0 : mfY = fCompareValue;
288 : }
289 :
290 0 : if(::basegfx::fTools::equal(mfZ, fCompareValue))
291 : {
292 0 : mfZ = fCompareValue;
293 : }
294 : }
295 0 : }
296 :
297 : static const B3DTuple& getEmptyTuple();
298 : };
299 :
300 : // external operators
301 :
302 :
303 : inline B3DTuple minimum(const B3DTuple& rTupA, const B3DTuple& rTupB)
304 : {
305 : return B3DTuple(
306 : std::min(rTupB.getX(), rTupA.getX()),
307 : std::min(rTupB.getY(), rTupA.getY()),
308 : std::min(rTupB.getZ(), rTupA.getZ()));
309 : }
310 :
311 : inline B3DTuple maximum(const B3DTuple& rTupA, const B3DTuple& rTupB)
312 : {
313 : return B3DTuple(
314 : std::max(rTupB.getX(), rTupA.getX()),
315 : std::max(rTupB.getY(), rTupA.getY()),
316 : std::max(rTupB.getZ(), rTupA.getZ()));
317 : }
318 :
319 : inline B3DTuple absolute(const B3DTuple& rTup)
320 : {
321 : B3DTuple aAbs(
322 : fabs(rTup.getX()),
323 : fabs(rTup.getY()),
324 : fabs(rTup.getZ()));
325 : return aAbs;
326 : }
327 :
328 0 : inline B3DTuple interpolate(const B3DTuple& rOld1, const B3DTuple& rOld2, double t)
329 : {
330 0 : if(rOld1 == rOld2)
331 : {
332 0 : return rOld1;
333 : }
334 0 : else if(0.0 >= t)
335 : {
336 0 : return rOld1;
337 : }
338 0 : else if(1.0 <= t)
339 : {
340 0 : return rOld2;
341 : }
342 : else
343 : {
344 : return B3DTuple(
345 0 : ((rOld2.getX() - rOld1.getX()) * t) + rOld1.getX(),
346 0 : ((rOld2.getY() - rOld1.getY()) * t) + rOld1.getY(),
347 0 : ((rOld2.getZ() - rOld1.getZ()) * t) + rOld1.getZ());
348 : }
349 : }
350 :
351 0 : inline B3DTuple average(const B3DTuple& rOld1, const B3DTuple& rOld2)
352 : {
353 : return B3DTuple(
354 0 : rOld1.getX() == rOld2.getX() ? rOld1.getX() : (rOld1.getX() + rOld2.getX()) * 0.5,
355 0 : rOld1.getY() == rOld2.getY() ? rOld1.getY() : (rOld1.getY() + rOld2.getY()) * 0.5,
356 0 : rOld1.getZ() == rOld2.getZ() ? rOld1.getZ() : (rOld1.getZ() + rOld2.getZ()) * 0.5);
357 : }
358 :
359 : inline B3DTuple average(const B3DTuple& rOld1, const B3DTuple& rOld2, const B3DTuple& rOld3)
360 : {
361 : return B3DTuple(
362 : (rOld1.getX() == rOld2.getX() && rOld2.getX() == rOld3.getX()) ? rOld1.getX() : (rOld1.getX() + rOld2.getX() + rOld3.getX()) * (1.0 / 3.0),
363 : (rOld1.getY() == rOld2.getY() && rOld2.getY() == rOld3.getY()) ? rOld1.getY() : (rOld1.getY() + rOld2.getY() + rOld3.getY()) * (1.0 / 3.0),
364 : (rOld1.getZ() == rOld2.getZ() && rOld2.getZ() == rOld3.getZ()) ? rOld1.getZ() : (rOld1.getZ() + rOld2.getZ() + rOld3.getZ()) * (1.0 / 3.0));
365 : }
366 :
367 0 : inline B3DTuple operator+(const B3DTuple& rTupA, const B3DTuple& rTupB)
368 : {
369 0 : B3DTuple aSum(rTupA);
370 0 : aSum += rTupB;
371 0 : return aSum;
372 : }
373 :
374 0 : inline B3DTuple operator-(const B3DTuple& rTupA, const B3DTuple& rTupB)
375 : {
376 0 : B3DTuple aSub(rTupA);
377 0 : aSub -= rTupB;
378 0 : return aSub;
379 : }
380 :
381 : inline B3DTuple operator/(const B3DTuple& rTupA, const B3DTuple& rTupB)
382 : {
383 : B3DTuple aDiv(rTupA);
384 : aDiv /= rTupB;
385 : return aDiv;
386 : }
387 :
388 0 : inline B3DTuple operator*(const B3DTuple& rTupA, const B3DTuple& rTupB)
389 : {
390 0 : B3DTuple aMul(rTupA);
391 0 : aMul *= rTupB;
392 0 : return aMul;
393 : }
394 :
395 0 : inline B3DTuple operator*(const B3DTuple& rTup, double t)
396 : {
397 0 : B3DTuple aNew(rTup);
398 0 : aNew *= t;
399 0 : return aNew;
400 : }
401 :
402 : inline B3DTuple operator*(double t, const B3DTuple& rTup)
403 : {
404 : B3DTuple aNew(rTup);
405 : aNew *= t;
406 : return aNew;
407 : }
408 :
409 0 : inline B3DTuple operator/(const B3DTuple& rTup, double t)
410 : {
411 0 : B3DTuple aNew(rTup);
412 0 : aNew /= t;
413 0 : return aNew;
414 : }
415 :
416 : inline B3DTuple operator/(double t, const B3DTuple& rTup)
417 : {
418 : B3DTuple aNew(rTup);
419 : aNew /= t;
420 : return aNew;
421 : }
422 :
423 : /** Round double to nearest integer for 3D tuple
424 :
425 : @return the nearest integer for this tuple
426 : */
427 : BASEGFX_DLLPUBLIC B3ITuple fround(const B3DTuple& rTup);
428 : } // end of namespace basegfx
429 :
430 : #endif // INCLUDED_BASEGFX_TUPLE_B3DTUPLE_HXX
431 :
432 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|