45#ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_TRIANGLE_2D_INL
46#define LASS_GUARDIAN_OF_INCLUSION_PRIM_TRIANGLE_2D_INL
84 LASS_ASSERT(isInRange(vertexIndex));
85 return vertices_[vertexIndex];
95 LASS_ASSERT(isInRange(vertexIndex));
96 return vertices_[vertexIndex];
106 const size_t i = num::mod(vertexIndex,
static_cast<unsigned>(size_));
107 LASS_ASSERT(isInRange(i));
118 const size_t i = num::mod(vertexIndex,
static_cast<unsigned>(size_));
119 LASS_ASSERT(isInRange(i));
130 return TLineSegment(
at(tailVertexIndex),
at(tailVertexIndex + 1));
140 return at(tailVertexIndex + 1) -
at(tailVertexIndex);
152 return vertices_[0] == vertices_[1] && vertices_[0] == vertices_[2];
172 static_assert(size_ == 3);
173 return perpDot(vertices_[1] - vertices_[0], vertices_[2] - vertices_[0]) / T(2);
193 return distance(vertices_[0], vertices_[1]) +
194 distance(vertices_[1], vertices_[2]) +
195 distance(vertices_[2], vertices_[0]);
203const typename Triangle2D<T>::TPointH
206 TPointH result = vertices_[0] + vertices_[1] + vertices_[2];
214template <
typename T>
inline
215const typename Triangle2D<T>::TPointH
253 if (
area > TNumTraits::zero)
257 else if (
area < TNumTraits::zero)
287 perpDot(vertices_[1] - vertices_[0], point - vertices_[0]) >= TNumTraits::zero &&
288 perpDot(vertices_[2] - vertices_[1], point - vertices_[1]) >= TNumTraits::zero &&
289 perpDot(vertices_[0] - vertices_[2], point - vertices_[2]) >= TNumTraits::zero;
295Side Triangle2D<T>::classify(
const TPoint& point)
const
307 std::swap(vertices_[0], vertices_[2]);
317bool Triangle2D<T>::isInRange(
size_t vertexIndex)
const
319 return vertexIndex < size_;
329const T squaredDistance(
const Triangle2D<T>& triangle,
const Point2D<T>& point)
331 typedef typename Triangle2D<T>::TPoint TPoint;
332 typedef typename Triangle2D<T>::TVector TVector;
333 typedef typename Triangle2D<T>::TValue TValue;
334 typedef typename Triangle2D<T>::TNumTraits TNumTraits;
336 TValue sqrBest = TNumTraits::infinity;
337 for (
size_t k1 = 0, k0 = 2; k1 < 3; k0 = k1++)
339 const TPoint& tail = triangle[k0];
340 const TPoint& head = triangle[k1];
341 const TVector vector = point - tail;
342 const TVector edge = head - tail;
343 const TValue t = dot(vector, edge);
344 const TValue tMax = dot(edge, edge);
345 if (t > 0 && t < tMax)
347 const TVector rejected = vector - edge * (t / tMax);
348 sqrBest = std::min(sqrBest, rejected.squaredNorm());
350 sqrBest = std::min(sqrBest, vector.squaredNorm());
361const T distance(
const Triangle2D<T>& triangle,
const Point2D<T>& point)
363 return num::sqrt(squaredDistance(triangle, point));
369 template <
typename T>
370 bool hasSeperatingAxis(
const Triangle2D<T>& a,
const Triangle2D<T>& b)
373 typedef typename Triangle2D<T>::TVector TVector;
374 typedef typename Triangle2D<T>::TPoint TPoint;
377 for (
size_t i = 0; i < 3; ++i)
379 const TPoint& aTail = a[i];
380 const TPoint& aHead = a[j];
381 const TVector aEdge = aHead - aTail;
383 const T b0 = perpDot(aEdge, b[0] - aTail);
384 const T b1 = perpDot(aEdge, b[1] - aTail);
385 const T b2 = perpDot(aEdge, b[2] - aTail);
386 const T aRef = perpDot(aEdge, a[k] - aTail);
390 if ((b0 < 0 && b1 < 0 && b2 < 0) || (b0 > aRef && b1 > aRef && b2 > aRef))
397 if ((b0 > 0 && b1 > 0 && b2 > 0) || (b0 < aRef && b1 < aRef && b2 < aRef))
416 return !(impl::hasSeperatingAxis(a, b) || impl::hasSeperatingAxis(b, a));
424io::XmlOStream& operator<<(io::XmlOStream& ioOStream,
const Triangle2D<T>& iTriangle)
426 LASS_ENFORCE_STREAM(ioOStream) <<
"<Triangle2D>\n";
427 for (
unsigned i = 0; i < 3; ++i)
429 ioOStream <<
"<vertex id='" << i <<
"'>" << iTriangle[i] <<
"</vertex>\n";
431 ioOStream <<
"</Triangle2D>\n";
440std::ostream& operator<<(std::ostream& ioOStream,
const Triangle2D<T>& iTriangle)
442 LASS_ENFORCE_STREAM(ioOStream)
443 <<
"{" << iTriangle[0] <<
", " << iTriangle[1] <<
", " << iTriangle[2] <<
"}";
450lass::io::MatlabOStream& operator<<(lass::io::MatlabOStream& oOStream,
453 LASS_ENFORCE_STREAM(oOStream) <<
"lasthandle = patch(";
454 oOStream <<
"[" << iTriangle[0].x <<
"," << iTriangle[1].x <<
"," << iTriangle[2].x <<
"],";
455 oOStream <<
"[" << iTriangle[0].y <<
"," << iTriangle[1].y <<
"," << iTriangle[2].y <<
"],";
456 oOStream << oOStream.color() <<
");\n";
471 typedef typename Triangle2D<T>::TPoint TPoint;
472 typedef typename Triangle2D<T>::TPointH TPointH;
474 TPoint a = iT.
at(vertexIndex);
475 TPoint b = iT.
at(vertexIndex+1);
476 TPoint c = iT.
at(vertexIndex-1);
482 TLine pbisAb(ab, (b-a).perp());
483 TLine pbisAc(ac, (c-a).perp());
A very simple 2D polygon :)
bool isSimple() const
return true if polygon is simple, false if not.
int size() const
return number of vertices
const TPoint & operator[](size_t iIndexOfVertex) const
return vertex of polygon by its index, not wrapped, no bounds check.
const TVector vector(int iIndexOfTailVertex) const
return the vector between vertices at(iIndex) and at(iIndex + 1)\
bool contains(const TPoint &iP) const
return true when a point is inside or on the edge of a triangle.
const TPointH vertexCentroid() const
return the barycenter of all vertices.
bool isReflex(int iIndexOfVertex) const
return true if inner angle of vertex is reflex (is > 180 degrees).
Orientation orientation() const
return orientation of polygon.
const TValue perimeter() const
return sum of the lengths of all edges
bool isEmpty() const
return true if polygon has no vertices
const TPoint & at(int iIndexOfVertex) const
return vertex of polygon by its index, but wrap around the bounds.
void flip()
flip orientation of polygon.
bool isConvex() const
return true if polygon is convex, false if not.
Result intersect(const Triangle2D< U > &triangle, const Ray2D< U, NP, PP > &ray, U &t, const U &tMin=U())
T partialVoronoiArea(const Triangle2D< T > iT, int vertexIndex)
Returns the surface of the partial Voronoi cell constructed around vertex vertexIndex (say vertex a i...
const TValue signedArea() const
return signed polygon area.
const TLineSegment edge(int iIndexOfTailVertex) const
return the edge of the polygon between vertices at(iIndex) and at(iIndex + 1).
Triangle2D()
constructs an empty triangle.
const TValue area() const
return area of the polygons surface.
const TPointH surfaceCentroid() const
return the barycenter of all vertices.
T abs(const T &x)
if x < 0 return -x, else return x.
implementation details of lass::prim
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
@ rOne
there's exactly one answer, 1 output argument contains the answer
Library for Assembled Shared Sources.
const Point2D< T > affine() const
Return rescaled version of point with weight = 1.