45#ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_SIMPLE_POLYGON_3D_INL
46#define LASS_GUARDIAN_OF_INCLUSION_PRIM_SIMPLE_POLYGON_3D_INL
56template <
typename T,
class EP,
class NP>
57SimplePolygon3D<T, EP, NP>::SimplePolygon3D(
const TPlane& iPlane) : plane_(iPlane)
61template <
typename T,
class EP,
class NP>
62SimplePolygon3D<T, EP, NP>::SimplePolygon3D(
const TPoint& iA,
const TPoint& iB,
const TPoint& iC) :
73template <
typename T,
class EP,
class NP>
74const typename SimplePolygon3D<T, EP, NP>::TPoint&
77 LASS_ASSERT(iIndexOfVertex < vertices_.size());
78 return vertices_[iIndexOfVertex];
85template <
typename T,
class EP,
class NP>
86typename SimplePolygon3D<T, EP, NP>::TPoint&
89 LASS_ASSERT(iIndexOfVertex < vertices_.size());
90 return vertices_[iIndexOfVertex];
98template <
typename T,
class EP,
class NP>
99const typename SimplePolygon3D<T, EP, NP>::TPoint&
102 const size_t i = num::mod(iIndexOfVertex,
static_cast<unsigned>(vertices_.size()));
103 LASS_ASSERT(isInRange(i));
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));
125template <
typename T,
class EP,
class NP>
126const typename SimplePolygon3D<T, EP, NP>::TLineSegment
129 return SimplePolygon3D<T, EP, NP>::TLineSegment(
at(iIndexOfTailVertex),
at(iIndexOfTailVertex + 1));
136template <
typename T,
class EP,
class NP>
137const typename SimplePolygon3D<T, EP, NP>::TVector
140 return at(iIndexOfTailVertex + 1) -
at(iIndexOfTailVertex);
147template <
typename T,
class EP,
class NP>
148const typename SimplePolygon3D<T, EP, NP>::TPlane&
158template <
typename T,
class EP,
class NP>
159typename SimplePolygon3D<T, EP, NP>::TPlane&
169template <
typename T,
class EP,
class NP>
170const typename SimplePolygon3D<T, EP, NP>::TVector
173 return plane_.normal();
185template <
typename T,
class EP,
class NP>
188 return plane_.majorAxis();
195template <
typename T,
class EP,
class NP>
198 vertices_.push_back(iVertex);
204template <
typename T,
class EP,
class NP>
207 const size_t i = num::mod(iIndexOfVertex,
static_cast<unsigned>(vertices_.size()));
208 LASS_ASSERT(isInRange(i));
209 vertices_.insert(i, iVertex);
216template <
typename T,
class EP,
class NP>
219 const size_t i = num::mod(iIndexOfVertex,
static_cast<unsigned>(vertices_.size()));
220 LASS_ASSERT(isInRange(i));
228template <
typename T,
class EP,
class NP>
231 return vertices_.empty();
238template <
typename T,
class EP,
class NP>
241 return vertices_.size();
258template <
typename T,
class EP,
class NP>
259const typename SimplePolygon3D<T, EP, NP>::TValue
262 const size_t n =
size();
265 return TNumTraits::zero;
269 const TPoint& reference = vertices_[0];
270 TValue result = TNumTraits::zero;
271 for (
size_t prevI = 1, i = 2; i < n; prevI = i++)
273 const TVector a = vertices_[prevI] - reference;
274 const TVector b = vertices_[i] - reference;
275 result += dot(cross(a, b),
normal);
288template <
typename T,
class EP,
class NP>
289const typename SimplePolygon3D<T, EP, NP>::TValue
299template <
typename T,
class EP,
class NP>
300const typename SimplePolygon3D<T, EP, NP>::TValue
303 TValue result = TNumTraits::zero;
304 for (
int i = 0; i <
size(); ++i)
306 result += distance(
at(i).position,
at(i + 1).position);
317template <
typename T,
class EP,
class NP>
318const typename SimplePolygon3D<T, EP, NP>::TPointH
322 for (
size_t i = 0; i <
size(); ++i)
324 result += vertices_[i];
343template <
typename T,
class EP,
class NP>
344const typename SimplePolygon3D<T, EP, NP>::TPointH
347 const size_t n =
size();
354 const TPoint& reference = vertices_[0];
356 for (
size_t prevI = 1, i = 2; i < n; prevI = i++)
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;
381template <
typename T,
class EP,
class NP>
405template <
typename T,
class EP,
class NP>
413 TValue
sign = TNumTraits::zero;
414 for (
int i = 0; i <
size(); ++i)
417 if (
sign != s && s != TNumTraits::zero)
419 if (
sign != TNumTraits::zero)
438template <
typename T,
class EP,
class NP>
442 if (
area > TNumTraits::zero)
446 else if (
area < TNumTraits::zero)
461template <
typename T,
class EP,
class NP>
486template <
typename T,
class EP,
class NP>
489 const XYZ x = iAxis + 1;
490 const XYZ y = iAxis + 2;
493 const int n =
size();
494 for (
int i = 0; i < n; ++i)
496 result.
add(Point2D<T>(vertices_[i][x], vertices_[i][y]));
504template <
typename T,
class EP,
class NP>
505Side SimplePolygon3D<T, EP, NP>::classify(
const TPoint& iP)
const
519template <
typename T,
class EP,
class NP>
523 const XYZ x = major + 1;
524 const XYZ y = major + 2;
528 const size_t npol =
size();
529 for (i = 0, j = npol-1; i < npol; j = i++)
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]))
545template <
typename T,
class EP,
class NP>
549 std::reverse(vertices_.begin(), vertices_.end());
558template <
typename T,
class EP,
class NP>
559bool SimplePolygon3D<T, EP, NP>::isInRange(
size_t iIndexOfVertex)
const
561 return iIndexOfVertex < vertices_.size();
582template<
typename T,
class EP,
class NP,
class PP>
585 T& oT,
const T& iMinT)
587 typedef Point2D<T> TPoint;
588 typedef typename TPoint::TValue TValue;
612template <
typename T,
class EP1,
class NP1,
class EP2,
class NP2>
618 typedef typename TPoint::TValue TValue;
619 typedef typename TPoint::TNumTraits TNumTraits;
621 const size_t size = iPolygon.
size();
629 std::vector<T> e(size);
630 for (
size_t i = 0; i < size; ++i)
632 e[i] = iPlane.
equation(iPolygon[i]);
633 allOut &= (e[i] <= TNumTraits::zero);
634 allIn &= (e[i] >= TNumTraits::zero);
644 return TPolygon(iPolygon.
plane());
647 TPolygon result(iPolygon.
plane());
648 TPoint tail = iPolygon[size - 1];
649 TValue tailE = e[size - 1];
650 bool tailInside = tailE >= TNumTraits::zero;
652 for (
size_t i = 0; i < size; ++i)
654 const TPoint& head = iPolygon[i];
655 const TValue headE = e[i];
656 const bool headInside = headE >= TNumTraits::zero;
668 const TValue t = tailE / (tailE - headE);
669 LASS_ASSERT(0.0 <= t && t <= 1.0);
670 const TPoint p = tail + t * (head - tail);
679 const TValue t = tailE / (tailE - headE);
680 LASS_ASSERT(0.0 <= t && t <= 1.0);
681 const TPoint p = tail + t * (head - tail);
693 tailInside = headInside;
701template <
typename T,
class EP,
class NP>
704 const size_t n = iPolygon.
size();
705 LASS_ENFORCE_STREAM(ioOStream) <<
"<SimplePolygon3D>\n";
706 for (
size_t i = 0; i < n; ++i)
708 ioOStream <<
"<vertex id='" <<
static_cast<unsigned long>(i) <<
"'>" << iPolygon[i] <<
"</vertex>\n";
710 ioOStream <<
"<plane>" << iPolygon.
plane() <<
"</plane>\n";
711 ioOStream <<
"</SimplePolygon3D>\n";
717template <
typename T,
class EP,
class NP>
718std::ostream& operator<<(std::ostream& ioOStream,
const SimplePolygon3D<T, EP, NP>& iPolygon)
720 const size_t n = iPolygon.size();
721 LASS_ENFORCE_STREAM(ioOStream) <<
"{";
724 ioOStream << iPolygon[0];
726 for (
size_t i = 1; i < n; ++i)
728 ioOStream <<
", " << iPolygon[i];
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
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.
T abs(const T &x)
if x < 0 return -x, else return x.
T sign(const T &x)
if x < 0 return -1, else if x > 0 return 1, else return 0.
set of geometrical primitives
Side
Different sides of a surface.
@ sOutside
outside the surface
@ sInside
inside the surface
Orientation
enumeration of clockwise versus counterclockwise
@ oClockWise
clockwise orientation
@ oCounterClockWise
counterclockwise orientation
Result
meta information on the result you have from an operation like an intersection ...
@ rNone
operation has no answer, output arguments are meaningless
@ rOne
there's exactly one answer, 1 output argument contains the answer
Library for Assembled Shared Sources.
const Vector3D< T > normal() const
return a unit vector with same direction/sense as this vector.