89 T x =
sub(*b->origin, *
a->origin);
90 T y =
sub(*
c->origin, *
a->origin);
95 return dot(n,
sub(p, *(
a->origin))) >= 0;
104 auto e = f->outerComponent;
105 const T*
a = e->origin;
106 const T* b = e->next->origin;
107 const T*
c = e->next->next->origin;
120 f->outerComponent = e;
123 ep->origin = e->twin->origin;
125 ep->incidentFace = pe->incidentFace = e->incidentFace = f;
134 assert(e->prev->next == e);
135 assert(e->next->prev == e);
136 assert(e->twin->twin == e);
137 assert(e->prev->incidentFace == e->incidentFace);
138 assert(e->next->incidentFace == e->incidentFace);
140 assert(ep->prev->next == ep);
141 assert(ep->next->prev == ep);
142 assert(ep->prev->incidentFace == ep->incidentFace);
143 assert(ep->next->incidentFace == ep->incidentFace);
145 assert(pe->prev->next == pe);
146 assert(pe->next->prev == pe);
147 assert(pe->prev->incidentFace == pe->incidentFace);
148 assert(pe->next->incidentFace == pe->incidentFace);
150 assert(f->outerComponent->incidentFace == f);
167 for (
const auto& f : mFaces)
170 const T* x = e->origin;
171 const T* y = e->next->origin;
172 const T* z = e->next->next->origin;
177 double p = (
a + b +
c) / 2;
199 for (
const auto& f : mFaces)
202 const T* x = e->origin;
203 const T* y = e->next->origin;
204 const T* z = e->next->next->origin;
209 double p = (
a + b +
c) / 2;
212 double height =
distance(f, center);
237 ab->incidentFace = base;
238 mHalfEdges.push_back(ab);
239 mHalfEdges.push_back(ba);
247 bc->incidentFace = base;
248 mHalfEdges.push_back(bc);
249 mHalfEdges.push_back(cb);
257 ca->incidentFace = base;
258 mHalfEdges.push_back(ca);
259 mHalfEdges.push_back(ac);
261 base->outerComponent = ab;
271 mFaces.push_back(base);
282 mHalfEdges.push_back(bd);
283 mHalfEdges.push_back(db);
291 mHalfEdges.push_back(da);
292 mHalfEdges.push_back(ad);
300 mHalfEdges.push_back(dc);
301 mHalfEdges.push_back(cd);
305 ba->incidentFace = db->incidentFace = ad->incidentFace = bad;
312 bad->outerComponent = ba;
313 mFaces.push_back(bad);
316 ac->incidentFace = cd->incidentFace = da->incidentFace = acd;
323 acd->outerComponent = ac;
324 mFaces.push_back(acd);
327 cb->incidentFace = bd->incidentFace = dc->incidentFace = cbd;
334 cbd->outerComponent = cb;
335 mFaces.push_back(cbd);
340 assert(f->outerComponent->incidentFace == f);
345 assert(e->prev->next == e);
346 assert(e->next->prev == e);
347 assert(e->twin->twin == e);
348 assert(e->twin->next->origin == e->origin);
349 assert(e->prev->twin->origin == e->origin);
350 assert(e->prev->incidentFace == e->incidentFace);
351 assert(e->next->incidentFace == e->incidentFace);
358 mFaces.erase(remove_if(mFaces.begin(), mFaces.end(), [](
FacePtr f) { return f->toDelete; }),
363 std::vector<HalfEdgePtr> mHalfEdges;
364 std::vector<FacePtr> mFaces;
375 template <
typename T>
383 template <
class Po
int>
384 std::vector<const Point*>
387 std::vector<const Point*> tetraPoints;
391 const Point* tmp[6] = {&points[0],
398 for (
unsigned int p = 0; p < points.size(); p++)
400 if (points.at(p)[0] < (*tmp[0])[0])
402 tmp[0] = &points.at(p);
405 if (points.at(p)[0] > (*tmp[1])[0])
407 tmp[1] = &points.at(p);
410 if (points.at(p)[1] < (*tmp[2])[1])
412 tmp[2] = &points.at(p);
415 if (points.at(p)[1] > (*tmp[3])[1])
417 tmp[3] = &points.at(p);
420 if (points.at(p)[2] < (*tmp[4])[2])
422 tmp[4] = &points.at(p);
425 if (points.at(p)[2] > (*tmp[5])[2])
427 tmp[5] = &points.at(p);
432 for (
int i = 0; i < 6; i++)
434 for (
int j = i + 1; j < 6; j++)
450 for (
int i = 0; i < 6; i++)
464 for (
unsigned int i = 0; i < points.size(); i++)
477 tetraPoints.push_back(b);
478 tetraPoints.push_back(
a);
482 tetraPoints.push_back(
a);
483 tetraPoints.push_back(b);
486 tetraPoints.push_back(
c);
487 tetraPoints.push_back(d);
499 template <
class Po
int>
503 std::cout <<
"CH -----------------------------------------------------------------"
505 const double eps = 0.001;
508 auto tetraPoints = extremePoints<Point>(points);
510 assert(tetraPoints.size() == 4);
514 CH.
addTetrahedron(*tetraPoints[0], *tetraPoints[1], *tetraPoints[2], *tetraPoints[3]);
516 auto facesStack = CH.
faces();
517 assert(facesStack.size() == 4);
520 for (
unsigned int p = 0; p < points.size(); p++)
522 bool visible =
false;
527 for (
const auto& f : facesStack)
544 closestFace->visiblePoints.push_back(&(points.at(p)));
549 while (!facesStack.empty())
551 auto currentFace = facesStack.back();
552 facesStack.pop_back();
554 if (currentFace->visiblePoints.size() == 0)
564 const Point* point = NULL;
567 for (
const Point* p : currentFace->visiblePoints)
581 std::vector<typename ConvexHull<Point>::type::FacePtr> visibleFaces;
582 std::vector<typename ConvexHull<Point>::type::FacePtr> toVisit;
583 currentFace->lastVisitedBy = point;
584 visibleFaces.push_back(currentFace);
585 toVisit.push_back(currentFace);
589 while (!toVisit.empty())
591 currentFace = toVisit.back();
593 auto e = currentFace->outerComponent;
598 auto adjFace = e->twin->incidentFace;
600 if (adjFace->lastVisitedBy != point &&
603 adjFace->lastVisitedBy = point;
604 visibleFaces.push_back(adjFace);
605 toVisit.push_back(adjFace);
616 }
while (e != currentFace->outerComponent);
619 assert(horizonStart != NULL);
622 for (
auto v : visibleFaces)
628 std::vector<typename ConvexHull<Point>::type::HalfEdgePtr> horizon;
629 auto currentHorizon = horizonStart;
634 horizon.push_back(currentHorizon);
636 auto nextEdge = currentHorizon->next;
640 nextEdge = nextEdge->twin->next;
643 currentHorizon = nextEdge;
644 }
while (currentHorizon != horizonStart);
649 std::vector<typename ConvexHull<Point>::type::FacePtr> newFaces;
650 auto prev = horizon.back();
651 newFaces.push_back(CH.
addFace(prev, point));
653 for (
auto e : horizon)
655 if (e != horizon.back())
659 newFaces.push_back(f);
662 assert(prev->twin->origin == e->origin);
665 prev->next->twin = e->prev;
666 e->prev->twin = prev->next;
669 assert(e->prev->twin->twin == e->prev);
670 assert(e->prev->twin->origin == e->origin);
676 prev->next->twin = e->prev;
677 e->prev->twin = prev->next;
679 assert(e->prev->twin->twin == e->prev);
680 assert(e->prev->twin->origin == e->origin);
684 int visiblePoints = 0;
685 int assignedPoints = 0;
688 for (
auto&
v : visibleFaces)
690 for (
auto& p :
v->visiblePoints)
693 bool visible =
false;
698 for (
auto& f : newFaces)
715 closestFace->visiblePoints.push_back(p);
720 v->visiblePoints.clear();
724 for (
auto& f : newFaces)
726 if (!f->visiblePoints.empty())
728 facesStack.push_back(f);