23 #include <unordered_set> 26 #include "Triangulation.h" 35 class FortuneAlgorithm;
68 typename std::list<Vertex>::iterator it;
85 typename std::list<HalfEdge>::iterator it;
148 return mSites.size();
205 auto processedHalfEdges = std::unordered_set<HalfEdge*>();
206 auto verticesToRemove = std::unordered_set<Vertex*>();
207 for (
const auto& site : mSites)
209 auto halfEdge = site.face->outerComponent;
210 auto inside = box.contains(halfEdge->origin->point);
211 auto outerComponentDirty = !inside;
212 auto incomingHalfEdge =
static_cast<HalfEdge*
>(
nullptr);
213 auto outgoingHalfEdge =
static_cast<HalfEdge*
>(
nullptr);
214 auto incomingSide =
typename Box<T>::Side{};
215 auto outgoingSide =
typename Box<T>::Side{};
218 auto intersections = std::array<typename Box<T>::Intersection, 2>{};
219 auto nbIntersections = box.getIntersections(halfEdge->origin->point, halfEdge->destination->point, intersections);
220 auto nextInside = box.contains(halfEdge->destination->point);
221 auto nextHalfEdge = halfEdge->next;
223 if (!inside && !nextInside)
226 if (nbIntersections == 0)
228 verticesToRemove.emplace(halfEdge->origin);
229 removeHalfEdge(halfEdge);
232 else if (nbIntersections == 2)
234 verticesToRemove.emplace(halfEdge->origin);
235 if (processedHalfEdges.find(halfEdge->twin) != processedHalfEdges.end())
237 halfEdge->origin = halfEdge->twin->destination;
238 halfEdge->destination = halfEdge->twin->origin;
242 halfEdge->origin = createVertex(intersections[0].
point);
243 halfEdge->destination = createVertex(intersections[1].point);
245 if (outgoingHalfEdge !=
nullptr)
246 link(box, outgoingHalfEdge, outgoingSide, halfEdge, intersections[0].side);
247 if (incomingHalfEdge ==
nullptr)
249 incomingHalfEdge = halfEdge;
250 incomingSide = intersections[0].side;
252 outgoingHalfEdge = halfEdge;
253 outgoingSide = intersections[1].side;
254 processedHalfEdges.emplace(halfEdge);
260 else if (inside && !nextInside)
263 if (nbIntersections >= 1)
265 if (processedHalfEdges.find(halfEdge->twin) != processedHalfEdges.end())
266 halfEdge->destination = halfEdge->twin->origin;
268 halfEdge->destination = createVertex(intersections[0].
point);
269 outgoingHalfEdge = halfEdge;
270 outgoingSide = intersections[0].side;
271 processedHalfEdges.emplace(halfEdge);
277 else if (!inside && nextInside)
280 if (nbIntersections >= 1)
282 verticesToRemove.emplace(halfEdge->origin);
283 if (processedHalfEdges.find(halfEdge->twin) != processedHalfEdges.end())
284 halfEdge->origin = halfEdge->twin->destination;
286 halfEdge->origin = createVertex(intersections[0].
point);
287 if (outgoingHalfEdge !=
nullptr)
288 link(box, outgoingHalfEdge, outgoingSide, halfEdge, intersections[0].side);
289 if (incomingHalfEdge ==
nullptr)
291 incomingHalfEdge = halfEdge;
292 incomingSide = intersections[0].side;
294 processedHalfEdges.emplace(halfEdge);
299 halfEdge = nextHalfEdge;
302 }
while (halfEdge != site.face->outerComponent);
304 if (outerComponentDirty && incomingHalfEdge !=
nullptr)
305 link(box, outgoingHalfEdge, outgoingSide, incomingHalfEdge, incomingSide);
307 if (outerComponentDirty)
308 site.face->outerComponent = incomingHalfEdge;
311 for (
auto& vertex : verticesToRemove)
312 removeVertex(vertex);
330 auto sites = std::vector<Vector2<T>>();
331 for (
const auto&
face : mFaces)
333 auto area =
static_cast<T
>(0.0);
339 auto det = halfEdge->origin->point.
getDet(halfEdge->destination->point);
341 centroid += (halfEdge->origin->point + halfEdge->destination->point) * det;
342 halfEdge = halfEdge->next;
345 centroid *= 1.0 / (6.0 * area);
346 sites.push_back(centroid);
365 auto neighbors = std::vector<std::vector<std::size_t>>(mSites.size());
366 for (
auto i = std::size_t(0); i < mSites.size(); ++i)
368 auto face = mFaces[i];
370 while (halfEdge->prev !=
nullptr)
372 halfEdge = halfEdge->
prev;
376 while (halfEdge !=
nullptr)
378 if (halfEdge->twin !=
nullptr)
379 neighbors[i].push_back(halfEdge->twin->incidentFace->site->index);
380 halfEdge = halfEdge->
next;
389 std::vector<Site> mSites;
390 std::vector<Face> mFaces;
391 std::list<Vertex> mVertices;
392 std::list<HalfEdge> mHalfEdges;
401 mSites.reserve(points.size());
402 mFaces.reserve(points.size());
403 for (
auto i = std::size_t(0); i < points.size(); ++i)
407 mSites.back().face = &mFaces.back();
423 mVertices.emplace_back();
425 mVertices.back().it = std::prev(mVertices.end());
426 return &mVertices.back();
429 Vertex* createCorner(
Box<T> box,
typename Box<T>::Side side)
448 mHalfEdges.emplace_back();
450 mHalfEdges.back().it = std::prev(mHalfEdges.end());
453 return &mHalfEdges.back();
458 void link(
Box<T> box,
HalfEdge* start,
typename Box<T>::Side startSide,
HalfEdge* end,
typename Box<T>::Side endSide)
460 auto halfEdge = start;
461 auto side =
static_cast<int>(startSide);
462 while (side != static_cast<int>(endSide))
464 side = (side + 1) % 4;
466 halfEdge->next->prev = halfEdge;
467 halfEdge->next->origin = halfEdge->destination;
468 halfEdge->next->destination = createCorner(box,
static_cast<typename Box<T>::Side
>(side));
469 halfEdge = halfEdge->next;
472 halfEdge->next->prev = halfEdge;
475 halfEdge->
next->
origin = halfEdge->destination;
476 halfEdge->next->destination = end->
origin;
479 void removeVertex(
Vertex* vertex)
481 mVertices.erase(vertex->it);
484 void removeHalfEdge(
HalfEdge* halfEdge)
486 mHalfEdges.erase(halfEdge->it);
Data structure representing a partitioning of the space.
Class representing a box.
const Site * getSite(std::size_t i) const
Get a site.
const std::vector< Site > & getSites() const
Get sites.
const std::list< Vertex > & getVertices() const
Get vertices.
Triangulation computeTriangulation() const
Compute the triangulation induced by the diagram.
Implementation of Fortune's algorithm.
std::vector< Vector2< T > > computeLloydRelaxation() const
Compute a Lloyd relaxation.
Class representing a 2D vector.
const std::vector< Face > & getFaces() const
Get faces.
HalfEdge * outerComponent
std::size_t getNbSites() const
Get the number of sites.
Data structure representing a triangulation.
bool intersect(Box< T > box)
Compute the intersection between the diagram and a box.
T getDet(const Vector2< T > &other) const
Compute the determinant with another vector.
const Face * getFace(std::size_t i) const
Get a face.
Point associated with a face of the partitioning.
Structure representing a cell in the diagram.
const std::list< HalfEdge > & getHalfEdges() const
Get half-edges.