85 T x =
sub(*b->origin, *
a->origin);
86 T y =
sub(*
c->origin, *
a->origin);
91 return dot(n,
sub(p, *(
a->origin))) >= 0;
99 auto e = f->outerComponent;
100 const T*
a = e->origin;
101 const T* b = e->next->origin;
102 const T*
c = e->next->next->origin;
114 f->outerComponent = e;
117 ep->origin = e->twin->origin;
119 ep->incidentFace = pe->incidentFace = e->incidentFace = f;
128 assert(e->prev->next == e);
129 assert(e->next->prev == e);
130 assert(e->twin->twin == e);
131 assert(e->prev->incidentFace == e->incidentFace);
132 assert(e->next->incidentFace == e->incidentFace);
134 assert(ep->prev->next == ep);
135 assert(ep->next->prev == ep);
136 assert(ep->prev->incidentFace == ep->incidentFace);
137 assert(ep->next->incidentFace == ep->incidentFace);
139 assert(pe->prev->next == pe);
140 assert(pe->next->prev == pe);
141 assert(pe->prev->incidentFace == pe->incidentFace);
142 assert(pe->next->incidentFace == pe->incidentFace);
144 assert(f->outerComponent->incidentFace == f);
158 for (
const auto& f : mFaces)
161 const T* x = e->origin;
162 const T* y = e->next->origin;
163 const T* z = e->next->next->origin;
168 double p = (
a + b +
c) / 2;
187 for (
const auto& f : mFaces)
190 const T* x = e->origin;
191 const T* y = e->next->origin;
192 const T* z = e->next->next->origin;
197 double p = (
a + b +
c) / 2;
200 double height =
distance(f, center);
224 ab->incidentFace = base;
225 mHalfEdges.push_back(ab);
226 mHalfEdges.push_back(ba);
234 bc->incidentFace = base;
235 mHalfEdges.push_back(bc);
236 mHalfEdges.push_back(cb);
244 ca->incidentFace = base;
245 mHalfEdges.push_back(ca);
246 mHalfEdges.push_back(ac);
248 base->outerComponent = ab;
258 mFaces.push_back(base);
269 mHalfEdges.push_back(bd);
270 mHalfEdges.push_back(db);
278 mHalfEdges.push_back(da);
279 mHalfEdges.push_back(ad);
287 mHalfEdges.push_back(dc);
288 mHalfEdges.push_back(cd);
292 ba->incidentFace = db->incidentFace = ad->incidentFace = bad;
299 bad->outerComponent = ba;
300 mFaces.push_back(bad);
303 ac->incidentFace = cd->incidentFace = da->incidentFace = acd;
310 acd->outerComponent = ac;
311 mFaces.push_back(acd);
314 cb->incidentFace = bd->incidentFace = dc->incidentFace = cbd;
321 cbd->outerComponent = cb;
322 mFaces.push_back(cbd);
327 assert(f->outerComponent->incidentFace == f);
332 assert(e->prev->next == e);
333 assert(e->next->prev == e);
334 assert(e->twin->twin == e);
335 assert(e->twin->next->origin == e->origin);
336 assert(e->prev->twin->origin == e->origin);
337 assert(e->prev->incidentFace == e->incidentFace);
338 assert(e->next->incidentFace == e->incidentFace);
344 mFaces.erase(remove_if(mFaces.begin(),
353 std::vector<HalfEdgePtr> mHalfEdges;
354 std::vector<FacePtr> mFaces;
373 template<
class Po
int>
376 std::vector<const Point*> tetraPoints;
380 const Point* tmp[6] = {&points[0], &points[0],
381 &points[0], &points[0],
382 &points[0], &points[0]
385 for (
unsigned int p = 0; p < points.size(); p++)
387 if (points.at(p)[0] < (*tmp[0])[0])
389 tmp[0] = &points.at(p);
392 if (points.at(p)[0] > (*tmp[1])[0])
394 tmp[1] = &points.at(p);
397 if (points.at(p)[1] < (*tmp[2])[1])
399 tmp[2] = &points.at(p);
402 if (points.at(p)[1] > (*tmp[3])[1])
404 tmp[3] = &points.at(p);
407 if (points.at(p)[2] < (*tmp[4])[2])
409 tmp[4] = &points.at(p);
412 if (points.at(p)[2] > (*tmp[5])[2])
414 tmp[5] = &points.at(p);
419 for (
int i = 0; i < 6; i++)
421 for (
int j = i + 1; j < 6; j++)
437 for (
int i = 0; i < 6; i++)
451 for (
unsigned int i = 0; i < points.size(); i++)
464 tetraPoints.push_back(b);
465 tetraPoints.push_back(
a);
469 tetraPoints.push_back(
a);
470 tetraPoints.push_back(b);
473 tetraPoints.push_back(
c);
474 tetraPoints.push_back(d);
486 template<
class Po
int>
489 std::cout <<
"CH -----------------------------------------------------------------" << std::endl;
490 const double eps = 0.001;
493 auto tetraPoints = extremePoints<Point>(points);
495 assert(tetraPoints.size() == 4);
499 CH.
addTetrahedron(*tetraPoints[0], *tetraPoints[1], *tetraPoints[2], *tetraPoints[3]);
501 auto facesStack = CH.
faces();
502 assert(facesStack.size() == 4);
505 for (
unsigned int p = 0; p < points.size(); p++)
507 bool visible =
false;
512 for (
const auto& f : facesStack)
529 closestFace->visiblePoints.push_back(&(points.at(p)));
534 while (!facesStack.empty())
536 auto currentFace = facesStack.back();
537 facesStack.pop_back();
539 if (currentFace->visiblePoints.size() == 0)
549 const Point* point = NULL;
552 for (
const Point* p : currentFace->visiblePoints)
566 std::vector<typename ConvexHull<Point>::type::FacePtr> visibleFaces;
567 std::vector<typename ConvexHull<Point>::type::FacePtr> toVisit;
568 currentFace->lastVisitedBy = point;
569 visibleFaces.push_back(currentFace);
570 toVisit.push_back(currentFace);
574 while (!toVisit.empty())
576 currentFace = toVisit.back();
578 auto e = currentFace->outerComponent;
583 auto adjFace = e->twin->incidentFace;
587 adjFace->lastVisitedBy = point;
588 visibleFaces.push_back(adjFace);
589 toVisit.push_back(adjFace);
601 while (e != currentFace->outerComponent);
604 assert(horizonStart != NULL);
607 for (
auto v : visibleFaces)
613 std::vector<typename ConvexHull<Point>::type::HalfEdgePtr> horizon;
614 auto currentHorizon = horizonStart;
619 horizon.push_back(currentHorizon);
621 auto nextEdge = currentHorizon->next;
625 nextEdge = nextEdge->twin->next;
628 currentHorizon = nextEdge;
630 while (currentHorizon != horizonStart);
635 std::vector<typename ConvexHull<Point>::type::FacePtr> newFaces;
636 auto prev = horizon.back();
637 newFaces.push_back(CH.
addFace(prev, point));
639 for (
auto e : horizon)
641 if (e != horizon.back())
645 newFaces.push_back(f);
648 assert(prev->twin->origin == e->origin);
651 prev->next->twin = e->prev;
652 e->prev->twin = prev->next;
655 assert(e->prev->twin->twin == e->prev);
656 assert(e->prev->twin->origin == e->origin);
662 prev->next->twin = e->prev;
663 e->prev->twin = prev->next;
665 assert(e->prev->twin->twin == e->prev);
666 assert(e->prev->twin->origin == e->origin);
670 int visiblePoints = 0;
671 int assignedPoints = 0;
674 for (
auto&
v : visibleFaces)
676 for (
auto& p :
v->visiblePoints)
679 bool visible =
false;
684 for (
auto& f : newFaces)
701 closestFace->visiblePoints.push_back(p);
706 v->visiblePoints.clear();
710 for (
auto& f : newFaces)
712 if (!f->visiblePoints.empty())
714 facesStack.push_back(f);