42 #include "Triangulator.hh" 53 : polySize_(_pos.size()), numRemaningVertices_(_pos.size()), numTris_(0),
54 numReflexVertices_(0),
55 ok_(false), convex_(false)
69 numRemaningVertices_ = 0;
81 Vec3f n(0.0f, 0.0f, 0.0f);
83 for (
size_t i = 0; i < polySize_; ++i)
85 const size_t next = (i + 1) % polySize_;
87 Vec3f a = _pos[i] - _pos[next];
88 Vec3f b = _pos[i] + _pos[next];
96 pos_.resize(polySize_);
98 Vec3f axis[3] = {
Vec3f(1.0f, 0.0f, 0.0f),
Vec3f(0.0f, 1.0f, 0.0f), n };
104 while (std::abs(axis[0] | axis[2]) > 0.95f || (axis[0].sqrnorm() < 0.001f))
106 for (
int i = 0; i < 3; ++i)
107 axis[0][i] =
float(rand()) / float(RAND_MAX) * 2.0f - 1.0f;
113 axis[0] = axis[0] - axis[2] * (axis[0] | axis[2]);
115 axis[1] = axis[2] % axis[0];
118 for (
size_t i = 0; i < polySize_; ++i)
121 pos_[i][0] = axis[0] | _pos[i];
122 pos_[i][1] = axis[1] | _pos[i];
127 int reflexVertexID = 0;
129 for (
size_t i = 0; i < polySize_; ++i)
132 if (
isReflexVertex(pos_[i], pos_[(i + 1) % polySize_], pos_[(i + 2) % polySize_]))
134 ++numReflexVertices_;
135 reflexVertexID = (i + 1) % polySize_;
139 convex_ = !numReflexVertices_;
142 if (numReflexVertices_ <= 1)
145 numTris_ = polySize_ - 2;
146 tris_.resize(numTris_ * 3);
147 numRemaningVertices_ = 0;
150 for (
size_t i = 0; i < numTris_; ++i)
152 tris_[i * 3] = reflexVertexID;
153 tris_[i * 3 + 1] = (reflexVertexID + i + 1) % polySize_;
154 tris_[i * 3 + 2] = (reflexVertexID + i + 2) % polySize_;
185 return u[0] * v[1] - u[1] * v[0] < 0.0f;
190 int p = (i + polySize_ - 1) % polySize_;
191 int n = (i + 1) % polySize_;
196 float Triangulator::triangleAreaSign(
const Vec2f& v0,
const Vec2f& v1,
const Vec2f& v2)
const 199 return (v0[0] - v2[0]) * (v1[1] - v2[1]) - (v1[0] - v2[0]) * (v0[1] - v2[1]);
202 float Triangulator::distancePointToSegmentSq(
const Vec2f& v0,
const Vec2f& v1,
const Vec2f& pt)
const 204 Vec2f segment = v1 - v0;
206 float dp = vec | segment;
211 float segSq = segment.
sqrnorm();
215 return vec.
sqrnorm() - dp * dp * segSq;
221 bool Triangulator::pointInTriangle(
const Vec2f& v0,
const Vec2f& v1,
const Vec2f& v2,
const Vec2f& pt)
const 230 return triangleAreaSign(pt, v0, v1) >= 0.0f &&
231 triangleAreaSign(pt, v1, v2) >= 0.0f &&
232 triangleAreaSign(pt, v2, v0) >= 0.0f;
272 void Triangulator::initVertexList()
274 vertices_.resize(polySize_);
275 reflexVertices_.clear();
276 for (
size_t i = 0; i < polySize_; ++i)
278 size_t p = (i + polySize_ - 1) % polySize_;
279 size_t n = (i + 1) % polySize_;
283 if (vertices_[i].reflex)
284 reflexVertices_.push_back(&vertices_[i]);
290 int Triangulator::earClippingN3()
300 tris_.resize((polySize_ - 2) * 3);
302 int numIterations = 0;
305 while (numTris_ < polySize_ - 2)
308 bool hasEars =
false;
313 curVertex->reflex =
isReflexVertex(curVertex->prev->pos, curVertex->pos, curVertex->next->pos);
315 if (!curVertex->reflex)
321 for (
RingVertex* r = curVertex->next->next; r != curVertex->prev; r = r->next)
323 if (pointInTriangle(curVertex->prev->pos, curVertex->pos, curVertex->next->pos, r->pos))
335 tris_[numTris_ * 3] = curVertex->prev->id;
336 tris_[numTris_ * 3 + 1] = curVertex->id;
337 tris_[numTris_ * 3 + 2] = curVertex->next->id;
341 curVertex->prev->next = curVertex->next;
342 curVertex->next->prev = curVertex->prev;
348 curVertex = curVertex->next;
350 }
while (curVertex != firstVertex);
352 firstVertex = firstVertex->next;
355 if (!hasEars && (numTris_ + 2 < polySize_))
357 for (
RingVertex* iteratorVertex = firstVertex->next; iteratorVertex != firstVertex->prev; iteratorVertex = iteratorVertex->next)
359 tris_[numTris_ * 3] = firstVertex->id;
360 tris_[numTris_ * 3 + 1] = iteratorVertex->id;
361 tris_[numTris_ * 3 + 2] = iteratorVertex->next->id;
365 assert(numTris_ == polySize_ - 2);
374 int Triangulator::earClippingN2()
387 numRemaningVertices_ = polySize_;
388 int numIterations = 0;
390 tris_.resize((polySize_ - 2) * 3);
393 while (numRemaningVertices_ > 3)
398 if (!curVertex->reflex)
402 for (std::list<RingVertex*>::iterator it = reflexVertices_.begin(); isEar && it != reflexVertices_.end(); ++it)
405 if (*it == curVertex->prev || *it == curVertex->next)
409 if (pointInTriangle(curVertex->prev->pos, curVertex->pos, curVertex->next->pos, (*it)->pos))
425 if (numTries > numRemaningVertices_)
436 curVertex = curVertex->next;
442 if (numRemaningVertices_ == 3)
444 tris_[numTris_ * 3 + 0] = curVertex->prev->id;
445 tris_[numTris_ * 3 + 1] = curVertex->id;
446 tris_[numTris_ * 3 + 2] = curVertex->next->id;
454 bool Triangulator::updateReflexVertex(
RingVertex* v)
463 reflexVertices_.remove(v);
469 void Triangulator::addEar(
RingVertex* _earTip)
472 tris_[numTris_ * 3 + 0] = _earTip->prev->id;
473 tris_[numTris_ * 3 + 1] = _earTip->id;
474 tris_[numTris_ * 3 + 2] = _earTip->next->id;
477 _earTip->prev->next = _earTip->next;
478 _earTip->next->prev = _earTip->prev;
481 updateReflexVertex(_earTip->prev);
482 updateReflexVertex(_earTip->next);
484 --numRemaningVertices_;
virtual ~Triangulator()
Destructor.
Namespace providing different geometric functions concerning angles.
VectorT< float, 3 > Vec3f
Triangulator(const std::vector< Vec3f > &_pos)
Execute the triangulation algorithm on a polygon.
decltype(std::declval< S >() *std::declval< S >()) sqrnorm() const
compute squared euclidean norm
bool isReflexVertex(int _i) const
Check if a vertex is reflex.
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())