Library of Assembled Shared Sources
simple_polygon_3d.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_SIMPLE_POLYGON_3D_INL
46#define LASS_GUARDIAN_OF_INCLUSION_PRIM_SIMPLE_POLYGON_3D_INL
47
48#include "prim_common.h"
49#include "simple_polygon_3d.h"
50
51namespace lass
52{
53namespace prim
54{
55
56template <typename T, class EP, class NP>
57SimplePolygon3D<T, EP, NP>::SimplePolygon3D(const TPlane& iPlane) : plane_(iPlane)
58{
59}
60
61template <typename T, class EP, class NP>
62SimplePolygon3D<T, EP, NP>::SimplePolygon3D(const TPoint& iA, const TPoint& iB, const TPoint& iC) :
63 plane_(iA,iB,iC)
64{
65 add(iA);
66 add(iB);
67 add(iC);
68}
69
70
71/** return vertex of polygon by its index, not wrapped, no bounds check.
72 */
73template <typename T, class EP, class NP>
74const typename SimplePolygon3D<T, EP, NP>::TPoint&
75SimplePolygon3D<T, EP, NP>::operator[](size_t iIndexOfVertex) const
76{
77 LASS_ASSERT(iIndexOfVertex < vertices_.size());
78 return vertices_[iIndexOfVertex];
79}
80
81
82
83/** return vertex of polygon by its index, not wrapped, no bounds check.
84 */
85template <typename T, class EP, class NP>
86typename SimplePolygon3D<T, EP, NP>::TPoint&
88{
89 LASS_ASSERT(iIndexOfVertex < vertices_.size());
90 return vertices_[iIndexOfVertex];
91}
92
93
94
95/** return vertex of polygon by its index, but wrap around the bounds.
96 * this->at(-1) will return the same vertex as this->at(this->size() - 1);
97 */
98template <typename T, class EP, class NP>
99const typename SimplePolygon3D<T, EP, NP>::TPoint&
100SimplePolygon3D<T, EP, NP>::at(int iIndexOfVertex) const
101{
102 const size_t i = num::mod(iIndexOfVertex, static_cast<unsigned>(vertices_.size()));
103 LASS_ASSERT(isInRange(i));
104 return vertices_[i];
105}
106
109/** return vertex of polygon by its index, but wrap around the bounds.
110 * this->at(-1) will return the same vertex as this->at(this->size() - 1);
111 */
112template <typename T, class EP, class NP>
113typename SimplePolygon3D<T, EP, NP>::TPoint&
116 const size_t i = num::mod(iIndexOfVertex, static_cast<unsigned>(vertices_.size()));
117 LASS_ASSERT(isInRange(i));
118 return vertices_[i];
121
123/** return the edge of the polygon between vertices at(iIndex) and at(iIndex + 1).
124 */
125template <typename T, class EP, class NP>
126const typename SimplePolygon3D<T, EP, NP>::TLineSegment
127SimplePolygon3D<T, EP, NP>::edge(int iIndexOfTailVertex) const
129 return SimplePolygon3D<T, EP, NP>::TLineSegment(at(iIndexOfTailVertex), at(iIndexOfTailVertex + 1));
130}
133
134/** return the vector between vertices at(iIndex) and at(iIndex + 1)\
135 */
136template <typename T, class EP, class NP>
137const typename SimplePolygon3D<T, EP, NP>::TVector
138SimplePolygon3D<T, EP, NP>::vector(int iIndexOfTailVertex) const
139{
140 return at(iIndexOfTailVertex + 1) - at(iIndexOfTailVertex);
142
144
145/** return support plane of polygon.
146 */
147template <typename T, class EP, class NP>
148const typename SimplePolygon3D<T, EP, NP>::TPlane&
150{
151 return plane_;
152}
153
154
155
156/** access support plane of polygon.
157 */
158template <typename T, class EP, class NP>
159typename SimplePolygon3D<T, EP, NP>::TPlane&
161{
162 return plane_;
163}
164
165
166
167/** return normal of plane
168 */
169template <typename T, class EP, class NP>
170const typename SimplePolygon3D<T, EP, NP>::TVector
172{
173 return plane_.normal();
174}
175
176
177
178/** determines the major axis of the normal vector.
179 * The major axis is the one with the largest (absolute) component value. e.g. if the normal
180 * vector is (-1, 4, -8), this will be the @e z axis because abs(-8) > abs(4) > abs(-1).
181 * In case there's more than one major axis possible, the "highest" index is choosen. e.g.
182 * if the normal vector is (1, 1, 0), then @e y axis will be choosen, because @e y has a higher
183 * index than @e x .
184 */
185template <typename T, class EP, class NP>
187{
188 return plane_.majorAxis();
189}
190
191
192
193/** add a point at the "end" of the vertex list
194 */
195template <typename T, class EP, class NP>
196void SimplePolygon3D<T, EP, NP>::add(const TPoint& iVertex)
197{
198 vertices_.push_back(iVertex);
199}
200
201
202/** insert a vertex at iIndex (so it will sit before the current at(iIndex)).
203 */
204template <typename T, class EP, class NP>
205void SimplePolygon3D<T, EP, NP>::insert(int iIndexOfVertex, const TPoint& iVertex)
206{
207 const size_t i = num::mod(iIndexOfVertex, static_cast<unsigned>(vertices_.size()));
208 LASS_ASSERT(isInRange(i));
209 vertices_.insert(i, iVertex);
210}
211
212
213
214/** remove the vertex at(iIndex)
215 */
216template <typename T, class EP, class NP>
218{
219 const size_t i = num::mod(iIndexOfVertex, static_cast<unsigned>(vertices_.size()));
220 LASS_ASSERT(isInRange(i));
221 vertices_.remove(i);
222}
223
224
225
226/** return true if polygon has no vertices
227 */
228template <typename T, class EP, class NP>
230{
231 return vertices_.empty();
232}
233
234
235
236/** return number of vertices
237 */
238template <typename T, class EP, class NP>
240{
241 return vertices_.size();
242}
243
244
245
246/** return signed polygon area.
247 *
248 * <i>The area of a convex polygon is defined to be positive if the points are arranged in a
249 * counterclockwise order, and negative if they are in clockwise order.</i>,
250 * Eric W. Weisstein. "Polygon Area." From MathWorld--A Wolfram Web Resource.
251 * http://mathworld.wolfram.com/PolygonArea.html
252 *
253 * @par Algorithm:
254 * comp.graphics.algorithms Frequently Asked Questions:
255 * Subject 2.01: "How do I find the area of a polygon?"
256 * http://www.faqs.org/faqs/graphics/algorithms-faq/
257 */
258template <typename T, class EP, class NP>
259const typename SimplePolygon3D<T, EP, NP>::TValue
261{
262 const size_t n = size();
263 if (n < 3)
264 {
265 return TNumTraits::zero;
266 }
267
268 const TVector normal = this->normal().normal();
269 const TPoint& reference = vertices_[0];
270 TValue result = TNumTraits::zero;
271 for (size_t prevI = 1, i = 2; i < n; prevI = i++)
272 {
273 const TVector a = vertices_[prevI] - reference;
274 const TVector b = vertices_[i] - reference;
275 result += dot(cross(a, b), normal);
276 }
277 return result / 2;
278}
279
280
281
282/** return area of the polygons surface.
283 *
284 * <i>The area of a surface is the amount of material needed to "cover" it completely</i>,
285 * Eric W. Weisstein. "Area." From MathWorld--A Wolfram Web Resource.
286 * http://mathworld.wolfram.com/Area.html
287 */
288template <typename T, class EP, class NP>
289const typename SimplePolygon3D<T, EP, NP>::TValue
291{
292 return num::abs(signedArea());
293}
294
295
296
297/** return sum of the lengths of all edges
298 */
299template <typename T, class EP, class NP>
300const typename SimplePolygon3D<T, EP, NP>::TValue
302{
303 TValue result = TNumTraits::zero;
304 for (int i = 0; i < size(); ++i)
305 {
306 result += distance(at(i).position, at(i + 1).position);
307 }
308 return result;
309}
310
311
312
313/** return the barycenter of all vertices.
314 * The barycenter is the homogenous sum of all vertices.
315 * @warning for non-convex polygons, it's NOT guaranteed that this center is inside the polygon.
316 */
317template <typename T, class EP, class NP>
318const typename SimplePolygon3D<T, EP, NP>::TPointH
320{
321 TPointH result;
322 for (size_t i = 0; i < size(); ++i)
323 {
324 result += vertices_[i];
325 }
326 return result;
327}
328
329
330
331/** return the centroid of the filled polygon.
332 *
333 * Eric W. Weisstein. "Geometric Centroid." From MathWorld--A Wolfram Web Resource.
334 * http://mathworld.wolfram.com/GeometricCentroid.html
335 *
336 * @par Algorithm:
337 * comp.graphics.algorithms Frequently Asked Questions:
338 * Subject 2.02: "How can the centroid of a polygon be computed?"
339 * http://www.faqs.org/faqs/graphics/algorithms-faq/
340 *
341 * @warning for non-convex polygons, it's NOT guaranteed that this center is inside the polygon.
342 */
343template <typename T, class EP, class NP>
344const typename SimplePolygon3D<T, EP, NP>::TPointH
346{
347 const size_t n = size();
348 if (n < 3)
349 {
350 return vertexCentroid();
351 }
352
353 const TVector normal = this->normal().normal();
354 const TPoint& reference = vertices_[0];
355 TPointH result;
356 for (size_t prevI = 1, i = 2; i < n; prevI = i++)
357 {
358 const TVector a = vertices_[prevI] - reference;
359 const TVector b = vertices_[i] - reference;
360 const TValue triangleWeight = dot(cross(a, b), normal);
361 const TPointH triangleCentroid = a + b + reference;
362 result += triangleWeight * triangleCentroid;
363 }
364}
365
366
367
368/** return true if polygon is simple, false if not.
369 *
370 * <i>A polygon P is said to be simple (or Jordan) if the only points of the plane belonging to
371 * two polygon edges of P are the polygon vertices of P. Such a polygon has a well defined
372 * interior and exterior. Simple polygons are topologically equivalent to a disk.</i>,
373 * Eric W. Weisstein. "Simple Polygon." From MathWorld--A Wolfram Web Resource.
374 * http://mathworld.wolfram.com/SimplePolygon.html
375 *
376 * In 3D, we test if the 2D mapping on the major axis is simple.
377 *
378 * @warning this is a brute force test. we simple test for all edges if they are not intersecting
379 * Hence, this is O(n^2).
380 */
381template <typename T, class EP, class NP>
383{
384 return mapping(majorAxis()).isSimple();
385}
386
387
388
389/** return true if polygon is convex, false if not.
390 * @warning assumes polygon is simple
391 *
392 * <i>A planar polygon is convex if it contains all the line segments connecting any pair of its
393 * points. Thus, for example, a regular pentagon is convex, while an indented pentagon is not.
394 * A planar polygon that is not convex is said to be a concave polygon</i>,
395 * Eric W. Weisstein. "Convex Polygon." From MathWorld--A Wolfram Web Resource.
396 * http://mathworld.wolfram.com/ConvexPolygon.html
397 *
398 * A simple polygon is convex if all the cross products of adjacent edges will be the same sign
399 * (we ignore zero signs, only + or - are taken in account), a concave polygon will have a mixture
400 * of cross product signs.
401 *
402 * A polygon with less than three vertices is always convex. A polygon with all colinear
403 * vertices is considered convex (not very usefull maybe, but convex).
404 */
405template <typename T, class EP, class NP>
407{
408 if (size() < 3)
409 {
410 return true;
411 }
412
413 TValue sign = TNumTraits::zero;
414 for (int i = 0; i < size(); ++i)
415 {
416 const TValue s = num::sign(perpDot(vector(i - 1), vector(i))); // Ax(-B) = BxA
417 if (sign != s && s != TNumTraits::zero)
418 {
419 if (sign != TNumTraits::zero)
420 {
421 return false;
422 }
423 else
424 {
425 sign = s;
426 }
427 }
428 }
429
430 return true;
431}
432
433
434
435/** return orientation of polygon
436 * @warning assumes polygon is simple
437 */
438template <typename T, class EP, class NP>
440{
441 const TValue area = signedArea();
442 if (area > TNumTraits::zero)
443 {
444 return oCounterClockWise;
445 }
446 else if (area < TNumTraits::zero)
447 {
448 return oClockWise;
449 }
450 else
451 {
452 return oInvalid;
453 }
454}
455
456
457
458/** return true if inner angle of vertex is reflex (is > 180 degrees).
459 * @warning assumes polygon is simple
460 */
461template <typename T, class EP, class NP>
462bool SimplePolygon3D<T, EP, NP>::isReflex(int iIndexOfVertex) const
463{
464 return dot(cross(vector(iIndexOfVertex - 1), vector(iIndexOfVertex)), normal()) < 0;
465}
466
467
468
469/** maps a 3D polygon as a 2D polygon by ignoring the component along an axis.
470 *
471 * if @a iAxis is @e z, then it's easy. We ignore the @e z component and we get a polygon with
472 * only the @e x and @e y components.
473 *
474 * if @a iAxis is @e x, then we have to keep the @e z axis while there's no @e z axis in 2D. We
475 * solve this by mapping the 3D @e y axis on the 2D @e x axis, and the 3D @e z axis on the
476 * 2D @e y axis.
477 *
478 * if @a iAxis is @e y, then we have a similar problem. This time the 3D @e z axis is mapped on
479 * the 2D @e x axis, and the 3D @e x axis is mapped on the 2D @e y axis.
480 *
481 * You can write this in short by saying the 2D @e x axis will correspond with 3D axis (@a iAxis
482 * + 1) and the 2D @e y axis with 3D axis (@a iAxis + 2).
483 *
484 * @todo explain this better
485 */
486template <typename T, class EP, class NP>
488{
489 const XYZ x = iAxis + 1;
490 const XYZ y = iAxis + 2;
491 SimplePolygon2D<T> result;
492
493 const int n = size();
494 for (int i = 0; i < n; ++i)
495 {
496 result.add(Point2D<T>(vertices_[i][x], vertices_[i][y]));
497 }
498
499 return result;
500}
501
502
503
504template <typename T, class EP, class NP>
505Side SimplePolygon3D<T, EP, NP>::classify(const TPoint& iP) const
506{
507 return contains(iP) ? sInside : sOutside;
508}
509
510
511
512/** return true if a point @a iP is inside the polygon, on condition @a iP is on the plane
513 *
514 * @par Algorithm:
515 * comp.graphics.algorithms Frequently Asked Questions:
516 * Subject 2.03: "How do I find if a point lies within a polygon?"
517 * http://www.faqs.org/faqs/graphics/algorithms-faq/
518 */
519template <typename T, class EP, class NP>
520bool SimplePolygon3D<T, EP, NP>::contains(const TPoint& iP) const
521{
522 const XYZ major = majorAxis();
523 const XYZ x = major + 1;
524 const XYZ y = major + 2;
525
526 size_t i, j;
527 bool c = false;
528 const size_t npol = size();
529 for (i = 0, j = npol-1; i < npol; j = i++)
530 {
531 const TPoint& a = vertices_[i];
532 const TPoint& b = vertices_[j];
533 if ((((a[y]<=iP[y]) && (iP[y]<b[y])) ||
534 ((b[y]<=iP[y]) && (iP[y]<a[y]))) &&
535 (iP[x] < (b[x] - a[x]) * (iP[y] - a[y]) / (b[y] - a[y]) + a[x]))
536 c = !c;
537 }
538 return c;
539}
540
541
542
543/** flip normal and reverse sequence of vertices
544 */
545template <typename T, class EP, class NP>
547{
548 plane_.flip();
549 std::reverse(vertices_.begin(), vertices_.end());
550}
551
552
553
554// --- private -------------------------------------------------------------------------------------
555
556/** return if index of vertex is in range of the std::vector
557 */
558template <typename T, class EP, class NP>
559bool SimplePolygon3D<T, EP, NP>::isInRange(size_t iIndexOfVertex) const
560{
561 return iIndexOfVertex < vertices_.size();
562}
563
564
565
566// --- free ----------------------------------------------------------------------------------------
567
568/** Find the intersection of a line segment and a simple polygon by their parameter t on the
569 * line segment.
570 * @relates lass::prim::LineSegment3D
571 * @relates lass::prim::SimplePolygon3D
572 *
573 * @param iPolygon [in] the simple polygon
574 * @param iSegment [in] the line segment
575 * @param oT [out] the parameter of the intersection point > @a iMinT.
576 * @param iMinT [in] the minimum t that may be returned as valid intersection.
577 * @return @arg rNone no intersections with @a oT > @a iMinT found
578 * @a oT is not assigned.
579 * @arg rOne a intersection with @a oT > @a iMinT is found
580 * @a oT is assigned.
581 */
582template<typename T, class EP, class NP, class PP>
583Result intersect(const SimplePolygon3D<T, EP, NP>& iPolygon,
584 const LineSegment3D<T, PP>& iSegment,
585 T& oT, const T& iMinT)
586{
587 typedef Point2D<T> TPoint;
588 typedef typename TPoint::TValue TValue;
589
590 TValue t;
591 if (intersect(iPolygon.plane(), iSegment, t, iMinT) == rOne)
592 {
593 if (iPolygon.contains(iSegment.point(t)))
594 {
595 oT = t;
596 return rOne;
597 }
598 }
599 return rNone;
600}
601
602
603
604/** Clip a polygon to a plane.
605 * @relates lass::prim::SimplePolygon3D
606 * @relates lass::prim::Plane3D
607 *
608 * @param iPlane [in] the plane to clip to
609 * @param iPolygon [in] the polygon to be clipped
610 * @return the clipped polygon.
611 */
612template <typename T, class EP1, class NP1, class EP2, class NP2>
613SimplePolygon3D<T, EP2, NP2> clip(const Plane3D<T, EP1, NP1>& iPlane,
614 const SimplePolygon3D<T, EP2, NP2>& iPolygon)
615{
616 typedef SimplePolygon3D<T, EP2, NP2> TPolygon;
617 typedef Point3D<T> TPoint;
618 typedef typename TPoint::TValue TValue;
619 typedef typename TPoint::TNumTraits TNumTraits;
620
621 const size_t size = iPolygon.size();
622 if (size < 2)
623 {
624 return iPolygon;
625 }
626
627 bool allOut = true;
628 bool allIn = true;
629 std::vector<T> e(size);
630 for (size_t i = 0; i < size; ++i)
631 {
632 e[i] = iPlane.equation(iPolygon[i]);
633 allOut &= (e[i] <= TNumTraits::zero);
634 allIn &= (e[i] >= TNumTraits::zero);
635 }
636
637 if (allIn)
638 {
639 return iPolygon;
640 }
641
642 if (allOut)
643 {
644 return TPolygon(iPolygon.plane());
645 }
646
647 TPolygon result(iPolygon.plane());
648 TPoint tail = iPolygon[size - 1];
649 TValue tailE = e[size - 1];
650 bool tailInside = tailE >= TNumTraits::zero;
651
652 for (size_t i = 0; i < size; ++i)
653 {
654 const TPoint& head = iPolygon[i];
655 const TValue headE = e[i];
656 const bool headInside = headE >= TNumTraits::zero;
657
658 if (tailInside)
659 {
660 if (headInside)
661 {
662 // both in, add this vertex
663 result.add(head);
664 }
665 else
666 {
667 // going out, add intersection point
668 const TValue t = tailE / (tailE - headE);
669 LASS_ASSERT(0.0 <= t && t <= 1.0);
670 const TPoint p = tail + t * (head - tail);
671 result.add(p);
672 }
673 }
674 else
675 {
676 if (headInside)
677 {
678 // coming in, add intersection point and this vertex.
679 const TValue t = tailE / (tailE - headE);
680 LASS_ASSERT(0.0 <= t && t <= 1.0);
681 const TPoint p = tail + t * (head - tail);
682 result.add(p);
683 result.add(head);
684 }
685 else
686 {
687 // both out, do nothing.
688 }
689 }
690
691 tail = head;
692 tailE = headE;
693 tailInside = headInside;
694 }
695
696 return result;
697}
698
699/** @relates lass::prim::SimplePolygon3D
700 */
701template <typename T, class EP, class NP>
702io::XmlOStream& operator<<(io::XmlOStream& ioOStream, const SimplePolygon3D<T, EP, NP>& iPolygon)
703{
704 const size_t n = iPolygon.size();
705 LASS_ENFORCE_STREAM(ioOStream) << "<SimplePolygon3D>\n";
706 for (size_t i = 0; i < n; ++i)
707 {
708 ioOStream << "<vertex id='" << static_cast<unsigned long>(i) << "'>" << iPolygon[i] << "</vertex>\n";
709 }
710 ioOStream << "<plane>" << iPolygon.plane() << "</plane>\n";
711 ioOStream << "</SimplePolygon3D>\n";
712 return ioOStream;
713}
714
715/** @relates lass::prim::SimplePolygon3D
716 */
717template <typename T, class EP, class NP>
718std::ostream& operator<<(std::ostream& ioOStream, const SimplePolygon3D<T, EP, NP>& iPolygon)
719{
720 const size_t n = iPolygon.size();
721 LASS_ENFORCE_STREAM(ioOStream) << "{";
722 if (n > 0)
723 {
724 ioOStream << iPolygon[0];
725 }
726 for (size_t i = 1; i < n; ++i)
727 {
728 ioOStream << ", " << iPolygon[i];
729 }
730 ioOStream << "}";
731 return ioOStream;
732}
733
734
735
736}
737
738}
739
740#endif
741
742// EOF
Output stream for writing a selection of geometric primitives to XML files.
const TPoint point(TParam iT) const
Return point on ray by it's parameter.
SimplePolygon3D< T, EP2, NP2 > clip(const Plane3D< T, EP1, NP1 > &iPlane, const SimplePolygon3D< T, EP2, NP2 > &iPolygon)
Clip a polygon to a plane.
convex or concave polygon in 2D (not selfintersecting, no holes)
void add(const TPoint &iVertex)
add a point at the "end" of the vertex list.
convex or concave polygon in 3D (not selfintersecting, no holes)
Result intersect(const SimplePolygon3D< T, EP, NP > &iPolygon, const LineSegment3D< T, PP > &iSegment, T &oT, const T &iMinT)
Find the intersection of a line segment and a simple polygon by their parameter t on the line segment...
void insert(int iIndexOfVertex, const TPoint &iVertex)
insert a vertex at iIndex (so it will sit before the current at(iIndex)).
const TValue area() const
return area of the polygons surface.
const XYZ majorAxis() const
determines the major axis of the normal vector.
const TValue perimeter() const
return sum of the lengths of all edges
bool contains(const TPoint &iP) const
return true if a point iP is inside the polygon, on condition iP is on the plane
const TPointH vertexCentroid() const
return the barycenter of all vertices.
const TVector vector(int iIndexOfTailVertex) const
return the vector between vertices at(iIndex) and at(iIndex + 1)\
bool isConvex() const
return true if polygon is convex, false if not.
const SimplePolygon2D< T > mapping(XYZ iAxis) const
maps a 3D polygon as a 2D polygon by ignoring the component along an axis.
size_t size() const
return number of vertices
void flip()
flip normal and reverse sequence of vertices
const TPoint & operator[](size_t iIndexOfVertex) const
return vertex of polygon by its index, not wrapped, no bounds check.
Orientation orientation() const
return orientation of polygon
const TValue signedArea() const
return signed polygon area.
const TPoint & at(int iIndexOfVertex) const
return vertex of polygon by its index, but wrap around the bounds.
bool isReflex(int iIndexOfVertex) const
return true if inner angle of vertex is reflex (is > 180 degrees).
void add(const TPoint &iVertex)
add a point at the "end" of the vertex list
const TVector normal() const
return normal of plane
bool isEmpty() const
return true if polygon has no vertices
void remove(int iIndexOfVertex)
remove the vertex at(iIndex)
const TPointH surfaceCentroid() const
return the centroid of the filled polygon.
bool isSimple() const
return true if polygon is simple, false if not.
const TLineSegment edge(int iIndexOfTailVertex) const
return the edge of the polygon between vertices at(iIndex) and at(iIndex + 1).
const TPlane & plane() const
return support plane of polygon.
Result intersect(const SimplePolygon3D< U, EP1, NP1 > &polygon, const Ray3D< U, NP2, PP2 > &triangle, U &t, const U &tMin)
cyclic iterator over xyz indices
Definition xyz.h:62
const TValue equation(const TPoint &iPoint) const
Return value of point in equation.
T sign(const T &x)
if x < 0 return -1, else if x > 0 return 1, else return 0.
Definition basic_ops.h:153
T abs(const T &x)
if x < 0 return -x, else return x.
Definition basic_ops.h:145
T sign(const T &x)
if x < 0 return -1, else if x > 0 return 1, else return 0.
set of geometrical primitives
Definition aabb_2d.h:81
Side
Different sides of a surface.
Definition side.h:79
@ sOutside
outside the surface
Definition side.h:86
@ sInside
inside the surface
Definition side.h:85
Orientation
enumeration of clockwise versus counterclockwise
Definition orientation.h:58
@ oClockWise
clockwise orientation
Definition orientation.h:60
@ oInvalid
invalid state
Definition orientation.h:59
@ oCounterClockWise
counterclockwise orientation
Definition orientation.h:61
Result
meta information on the result you have from an operation like an intersection ...
Definition result.h:74
@ rNone
operation has no answer, output arguments are meaningless
Definition result.h:76
@ rOne
there's exactly one answer, 1 output argument contains the answer
Definition result.h:77
Library for Assembled Shared Sources.
Definition config.h:53
const Vector3D< T > normal() const
return a unit vector with same direction/sense as this vector.