Library of Assembled Shared Sources
point_2d.inl
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2011 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45#ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_POINT_2D_INL
46#define LASS_GUARDIAN_OF_INCLUSION_PRIM_POINT_2D_INL
47
48#include "point_2d.h"
49
50namespace lass
51{
52namespace prim
53{
54
55template<typename T> inline
56Point2D<T>::Point2D():
57 x(TNumTraits::zero),
58 y(TNumTraits::zero)
59{
60 LASS_ASSERT(isZero());
61}
62
63
64
65template<typename T> inline
66Point2D<T>::Point2D(TParam x, TParam y):
67 x(x),
68 y(y)
69{
70}
71
72
73
74template<typename T>
75template<typename U>
76Point2D<T>::Point2D(const Point2D<U>& other):
77 x(static_cast<TValue>(other.x)),
78 y(static_cast<TValue>(other.y))
79{
80}
81
82
83
84template<typename T>
85template<typename U>
86Point2D<T>::Point2D(const Vector2D<U>& position):
87 x(static_cast<TValue>(position.x)),
88 y(static_cast<TValue>(position.y))
89{
90}
91
92
93
94template<typename T>
95template<typename U>
96Point2D<T>::Point2D(const U& x, const U& y):
97 x(static_cast<TValue>(x)),
98 y(static_cast<TValue>(y))
99{
100}
101
102
103
104template <typename T> inline
105const typename Point2D<T>::TVector
106Point2D<T>::position() const
107{
108 return TVector(x, y);
109}
110
111
112
113template<typename T> inline
114typename Point2D<T>::TConstReference
115Point2D<T>::operator[](size_t index) const
116{
117 LASS_ASSERT(index < dimension);
118 return *(&x + index);
119}
120
121
122
123template<typename T> inline
124typename Point2D<T>::TReference
125Point2D<T>::operator[](size_t index)
126{
127 LASS_ASSERT(index < dimension);
128 return *(&x + index);
129}
130
131
132
133/** Wrap index around range.
134 */
135template<typename T> inline
136typename Point2D<T>::TConstReference
137Point2D<T>::at(signed index) const
138{
139 return *(&x + num::mod(index, dimension));
140}
141
142
143
144/** Wrap index around range.
145 */
146template<typename T> inline
147typename Point2D<T>::TReference
148Point2D<T>::at(signed index)
149{
150 return *(&x + num::mod(index, dimension));
151}
152
153
154
155template<typename T>
156Point2D<T>&
157Point2D<T>::operator+=(const Vector2D<T>& offset)
158{
159 x += offset.x;
160 y += offset.y;
161 return *this;
162}
163
164
165
166template<typename T>
167Point2D<T>&
168Point2D<T>::operator-=(const Vector2D<T>& offset)
169{
170 x -= offset.x;
171 y -= offset.y;
172 return *this;
173}
174
175
176
177template<typename T>
178bool Point2D<T>::isZero() const
179{
180 return x == TNumTraits::zero && y == TNumTraits::zero;
181}
182
183
184
185/** Return true if at least one of the components is NaN
186 */
187template<typename T> inline
188bool Point2D<T>::isNaN() const
189{
190 return num::isNaN(x) || num::isNaN(y);
191}
192
193
194
195// --- FREE FUNCTIONS ---------------------------------------------------------------------------
196
197/** @relates lass::prim::Point2D
198 */
199template<typename T>
200bool operator==(const Point2D<T>& a, const Point2D<T>& b)
201{
202 return a.x == b.x && a.y == b.y;
203}
204
205
206
207/** @relates lass::prim::Point2D
208 */
209template<typename T> inline
210bool operator!=(const Point2D<T>& a, const Point2D<T>& b)
211{
212 return !(a == b);
213}
214
215
216
217/** @relates lass::prim::Point2D
218 */
219template<typename T> inline
220Point2D<T> operator+(const Point2D<T>& a, const Vector2D<T>& b)
221{
222 Point2D<T> result(a);
223 result += b;
224 return result;
225}
226
227
228
229/** @relates lass::prim::Point2D
230 */
231template<typename T> inline
232Point2D<T> operator+(const Vector2D<T>& a, const Point2D<T>& b)
233{
234 Point2D<T> result(b);
235 result += a;
236 return result;
237}
238
239
240
241/** @relates lass::prim::Point2D
242 */
243template<typename T> inline
244Point2D<T> operator-(const Point2D<T>& a, const Vector2D<T>& b)
245{
246 Point2D<T> result(a);
247 result -= b;
248 return result;
249}
250
251
252
253/** @relates lass::prim::Point2D
254 */
255template<typename T> inline
256Vector2D<T> operator-(const Point2D<T>& a, const Point2D<T>& b)
257{
258 return Vector2D<T>(a.x - b.x, a.y - b.y);
259}
260
261
262
263/** @relates lass::prim::Point2D
264 */
265template<typename T> inline
266typename Point2D<T>::TValue distance(const Point2D<T>& a, const Point2D<T>& b)
267{
268 const Vector2D<T> difference = a - b;
269 return difference.norm();
270}
271
272/** @relates lass::prim::Point2D
273 */
274template<typename T> inline
275typename Point2D<T>::TValue squaredDistance(const Point2D<T>& a, const Point2D<T>& b)
276{
277 const Vector2D<T> difference = a - b;
278 return difference.squaredNorm();
279}
280
281
282/** return a point with, for each coordinate, the minimum value of a and b
283 * @relates lass::prim::Point2D
284 */
285template<typename T>
286Point2D<T> pointwiseMin(const Point2D<T>& a, const Point2D<T>& b)
287{
288 return Point2D<T>(std::min(a.x, b.x), std::min(a.y, b.y));
289}
290
291
292
293/** return a point with, for each coordinate, the maximum value of a and b
294 * @relates lass::prim::Point2D
295 */
296template<typename T>
297Point2D<T> pointwiseMax(const Point2D<T>& a, const Point2D<T>& b)
298{
299 return Point2D<T>(std::max(a.x, b.x), std::max(a.y, b.y));
300}
301
302
303
304/** interpolate linearly between two points: a + t * (b - a)
305 * @relates lass::prim::Point2D
306 */
307template<typename T>
308inline Point2D<T> lerp(const Point2D<T>& a, const Point2D<T>& b, typename Point2D<T>::TParam t)
309{
310 return Point2D<T>(lerp(a.position(), b.position(), t));
311}
312
313
314
315/** @relates lass::prim::Point2D
316 */
317template<typename T>
318std::ostream& operator<<(std::ostream& stream, const Point2D<T>& b)
319{
320 LASS_ENFORCE_STREAM(stream) << b.position();
321 return stream;
322}
323
324
325
326/** @relates lass::prim::Point2D
327 */
328template<typename T>
329io::XmlOStream& operator<<(io::XmlOStream& stream, const Point2D<T>& b)
330{
331 LASS_ENFORCE_STREAM(stream)
332 << "<Point2D>" << b.x << " " << b.y << "</Point2D>\n";
333 return stream;
334}
335
336
337
338/** @relates lass::prim::Point2D
339 */
340template<typename T>
341lass::io::MatlabOStream& operator<<(lass::io::MatlabOStream& stream, const Point2D<T>& b)
342{
343 LASS_ENFORCE_STREAM(stream) << "lasthandle = line(";
344 stream << b.x << "," << b.y << ",";
345 stream << "'Color'," << stream.color() << ");\n";
346 stream << "set(lasthandle,'Marker','o');\n";
347 stream << "set(lasthandle,'markersize',2);\n";
348 return stream;
349}
350
351
352/** @relates lass::prim::Point2D
353 */
354template<typename T>
355std::istream& operator>>(std::istream& stream, Point2D<T>& b)
356{
357 Vector2D<T> temp;
358 LASS_ENFORCE_STREAM(stream) >> temp;
359 b = Point2D<T>(temp);
360 return stream;
361}
362
363/** returns twice signed area of triangle a,b,c
364 * @relates lass::prim::Point2D
365 */
366// based on floating point number theory the ordening of computation is optimised
367// for floating point or filtered arithmetic
368// when T is an exact type, a faster computation could be devised
369// see work from Shewchuk, Fortune and Van Wyck
370// the basic idea is to translate points a and b by c
371template<typename T> inline
372T doubleTriangleArea( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c )
373{
374 return perpDot(a-c,b-c);
375 /* more intuitive (and faster) but less precise version...
376 const Vector2D<T> a = a.position();
377 const Vector2D<T> b = b.position();
378 const Vector2D<T> c = c.position();
379 return perpDot(b, c) - perpDot(a, c) + perpDot(a, b);
380 */
381}
382
383// based on floating point number theory the ordening of computation is optimised
384// for floating point or filtered arithmetic
385// when T is an exact type, a faster computation could be devised
386// see work from Shewchuk, Fortune and Van Wyck
387// the basic idea is to translate points a and b by c
388template<typename T> inline
389T preciseDoubleTriangleArea( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c )
390{
391 return perpDot(a-c,b-c);
392}
393
394
395
396
397
398/** returns true when the line b->c is counter clockwise oriented with respect to a->b
399 * @relates lass::prim::Point2D
400 */
401template<typename T> inline
402bool ccw( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c )
403{
404 return doubleTriangleArea(a,b,c) > T();
405}
406
407/** returns true when the line b->c is clockwise oriented with respect to a->b
408 * @relates lass::prim::Point2D
409 */
410template<typename T> inline
411bool cw( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c )
412{
413 return doubleTriangleArea(a,b,c) < T();
414}
415
416
417/** returns true when the line b->c is counter clockwise oriented with respect to a->b.
418 * When c is in line of a and b also returns true.
419 * @relates lass::prim::Point2D
420 */
421template<typename T> inline
422bool weakCcw( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c )
423{
424 return doubleTriangleArea(a,b,c) >= T();
425}
426
427/** returns true when the line b->c is counter clockwise oriented with respect to a->b.
428 * When c is in line of a and b also returns true.
429 * @relates lass::prim::Point2D
430 */
431template<typename T> inline
432bool weakCw( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c )
433{
434 return doubleTriangleArea(a,b,c) <= T();
435}
436
437/** returns true when the point d is strictly (within numerical precision) in the circle
438 * going through a, b and c.
439 * @relates lass::prim::Point2D
440 * @note this test is used for establishing Delaunay neighborhoods and this tests
441 * numerical stability determines the overall stability of the Delaunay meshers
442 */
443template<typename T>
444bool inCircle( const Point2D<T>& a, const Point2D<T>& b, const Point2D<T>& c, const Point2D<T>& d )
445{
446 const T az = a.position().squaredNorm();
447 const T bz = b.position().squaredNorm();
448 const T cz = c.position().squaredNorm();
449 const T dz = d.position().squaredNorm();
450
451 T det = (az * doubleTriangleArea(b, c, d) - bz * doubleTriangleArea(a, c, d)
452 + cz * doubleTriangleArea(a, b, d) - dz * doubleTriangleArea(a, b, c));
453
454 return (det > T(0));
455}
456
457
458}
459
460}
461
462#endif
Output stream for writing a selection of geometric primitives to matlab M files.
T lerp(const T &a, const T &b, const T &f)
linear interpolation between a and b
set of geometrical primitives
Definition aabb_2d.h:81
Library for Assembled Shared Sources.
Definition config.h:53