NuTo
Numerics Tool
DelaunayVoronoi.h
Go to the documentation of this file.
1 /*
2  * DelaunayVoronoi.h
3  *
4  * Created on: 1 Sep 2015
5  * Author: ttitsche
6  */
7 #pragma once
8 
9 #include <iostream>
10 #include <Eigen/Dense>
11 
12 #include <array>
13 #include <list>
14 #include <set>
15 #include <map>
16 #include <vector>
17 #include <unordered_set>
18 #include <unordered_map>
19 #include <algorithm>
20 #include <cmath>
21 
22 #include <string>
23 
24 #include <fstream>
25 
26 class Edge
27 {
28 public:
29  Edge()
30  {
31  }
32 
33  Edge(Eigen::Vector2d rP0, Eigen::Vector2d rP1)
34  {
35  mPoints[0] = rP0;
36  mPoints[1] = rP1;
37  }
38 
39  const Eigen::Vector2d P0() const
40  {
41  return mPoints[0];
42  }
43 
44  const Eigen::Vector2d P1() const
45  {
46  return mPoints[1];
47  }
48 
49  bool operator==(const Edge& rOther) const
50  {
51  bool result = (P0() == rOther.P0() && P1() == rOther.P1()) || (P0() == rOther.P1() && P1() == rOther.P0());
52  return result;
53  }
54 
55  bool Contains(Eigen::Vector2d rPoint) const
56  {
57  if (P0() == rPoint || P1() == rPoint)
58  return true;
59  return false;
60  }
61 
62  void Info() const
63  {
64  std::cout << "E: (" << P0().transpose() << ") and (" << P1().transpose() << ") \n";
65  }
66 
67  size_t GetHash() const
68  {
69  return std::hash<double>()(P0().x()) + std::hash<double>()(P0().y()) + std::hash<double>()(P1().x()) +
70  std::hash<double>()(P1().y());
71  }
72 
75  double GetIntersectionLineParameter(const Eigen::Vector2d rPoint, const Eigen::Vector2d rDirection) const
76  {
77  const Eigen::Vector2d e = mPoints[1] - mPoints[0];
78  const Eigen::Vector2d& n = rDirection;
79 
80  double eXn = e.x() * n.y() - e.y() * n.x(); // pseudo cross product 2D
81  double nXe = -eXn;
82 
83  const Eigen::Vector2d D = rPoint - mPoints[0];
84 
85  double edgeParameter = (D.x() * n.y() - D.y() * n.x()) / eXn;
86  double lineParameter = (D.y() * e.x() - D.x() * e.y()) / nXe;
87 
88  if (edgeParameter < 0. || edgeParameter > 1.)
89  return -1.;
90 
91  return lineParameter;
92  }
93 
95  double GetDistance(Eigen::Vector2d rPoint) const
96  {
97  Eigen::Vector2d p = P1() - P0();
98  Eigen::Vector2d a = rPoint - P0();
99 
100  return (a - a.dot(p) * p / p.dot(p)).norm();
101  }
102 
103 private:
104  std::array<Eigen::Vector2d, 2> mPoints;
105 };
106 
107 class Triangle
108 {
109 public:
110  Triangle(Edge rE0, Edge rE1, Edge rE2)
111  {
112  mEdges[0] = rE0;
113  mEdges[1] = rE1;
114  mEdges[2] = rE2;
115  }
116 
117  std::array<Eigen::Vector2d, 3> GetUniquePoints() const
118  {
119  std::array<Eigen::Vector2d, 3> uniquePoints;
120  uniquePoints[0] = mEdges[0].P0();
121  uniquePoints[1] = mEdges[0].P1();
122 
123  if (mEdges[0].Contains(mEdges[1].P0()))
124  uniquePoints[2] = mEdges[1].P1();
125  else
126  uniquePoints[2] = mEdges[1].P0();
127 
128  assert(uniquePoints[0] != uniquePoints[1]);
129  assert(uniquePoints[0] != uniquePoints[2]);
130  assert(uniquePoints[1] != uniquePoints[2]);
131 
132  return uniquePoints;
133  }
134 
135  std::array<Edge, 3> GetEdges() const
136  {
137  return mEdges;
138  }
139 
140  bool Contains(const Eigen::Vector2d& rPoint) const
141  {
142  for (auto edge : mEdges)
143  if (edge.Contains(rPoint))
144  return true;
145  return false;
146  }
147 
148  bool Contains(Edge rEdge) const
149  {
150  for (auto edge : mEdges)
151  if (rEdge == edge)
152  return true;
153  return false;
154  }
155 
156  bool operator==(const Triangle& rOther) const
157  {
158  for (auto otherPoint : rOther.GetUniquePoints())
159  if (not Contains(otherPoint))
160  return false;
161 
162  return true;
163  }
164 
165  // https://en.wikipedia.org/wiki/Circumscribed_circle#Cartesian_coordinates_2
166  Eigen::Vector2d GetCircumcenter() const
167  {
168  auto points = GetUniquePoints();
169  Eigen::Vector2d A = points[0];
170  Eigen::Vector2d B = points[1];
171  Eigen::Vector2d C = points[2];
172 
173  double d = 2 * (A.x() * (B.y() - C.y()) + B.x() * (C.y() - A.y()) + C.x() * (A.y() - B.y()));
174 
175  double x = A.dot(A) * (B.y() - C.y()) + B.dot(B) * (C.y() - A.y()) + C.dot(C) * (A.y() - B.y());
176  double y = A.dot(A) * (C.x() - B.x()) + B.dot(B) * (A.x() - C.x()) + C.dot(C) * (B.x() - A.x());
177 
178  return Eigen::Vector2d(x / d, y / d);
179  }
180 
181  bool CircumcircleContainsPoint(const Eigen::Vector2d& rPoint) const
182  {
183  auto points = GetUniquePoints();
184  Eigen::Vector2d A = points[0];
185  Eigen::Vector2d B = points[1];
186  Eigen::Vector2d C = points[2];
187  Eigen::Vector2d D = rPoint;
188 
189  // check if clockwise oriented A --> B --> C ...
190  Eigen::Vector2d v1 = B - A;
191  Eigen::Vector2d v2 = C - A;
192 
193  double dir = v1.x() * v2.y() - v1.y() * v2.x();
194  // ... and swap B and C if not.
195  if (dir < 0.)
196  {
197  auto q = B;
198  B = C;
199  C = q;
200  }
201 
202  if (A == D || B == D || C == D)
203  return false;
204 
205  Eigen::Matrix3d matr;
206 
207  matr(0, 0) = A.x() - D.x();
208  matr(1, 0) = B.x() - D.x();
209  matr(2, 0) = C.x() - D.x();
210 
211  matr(0, 1) = A.y() - D.y();
212  matr(1, 1) = B.y() - D.y();
213  matr(2, 1) = C.y() - D.y();
214 
215  matr(0, 2) = A.x() * A.x() - D.x() * D.x() + A.y() * A.y() - D.y() * D.y();
216  matr(1, 2) = B.x() * B.x() - D.x() * D.x() + B.y() * B.y() - D.y() * D.y();
217  matr(2, 2) = C.x() * C.x() - D.x() * D.x() + C.y() * C.y() - D.y() * D.y();
218 
219  return matr.determinant() > 0;
220  }
221 
222  void Info() const
223  {
224  auto points = GetUniquePoints();
225  std::cout << "T: \n"
226  << points[0].transpose() << " | " << points[1].transpose() << " | " << points[2].transpose()
227  << " | \n";
228  }
229 
230 private:
231  std::array<Edge, 3> mEdges;
232 };
233 
234 class Polygon
235 {
236 public:
238  {
239  }
240 
241  Polygon(std::vector<Eigen::Vector2d> rPoints)
242  : mPoints(rPoints)
243  {
244  SortAndRemoveDoublicates();
245  }
246 
247  std::vector<Eigen::Vector2d> GetPoints()
248  {
249  return mPoints;
250  }
251 
253  {
254  // find some point inside the (convex) voronoi polygon
255  Eigen::Vector2d center(0., 0.);
256  for (auto point : mPoints)
257  center += point;
258  center /= mPoints.size();
259 
260  std::map<double, Eigen::Vector2d> anglesPoints;
261 
262  // get angle of each voronoi point
263  for (auto vp : mPoints)
264  {
265  double angle = atan2(vp.x() - center.x(), vp.y() - center.y());
266  anglesPoints[angle] = vp;
267  }
268 
269  std::vector<Eigen::Vector2d> sortedUniqueVoronoiPoints;
270 
271  // two points with an angle difference < delta
272  // are the same points and are only considered once.
273  double delta = 1.e-6;
274  double lastAngle = -10;
275  for (auto pair : anglesPoints)
276  {
277  double currentAngle = pair.first;
278  if (currentAngle - lastAngle > delta)
279  {
280  sortedUniqueVoronoiPoints.push_back(pair.second);
281  lastAngle = currentAngle;
282  }
283  }
284  mPoints = sortedUniqueVoronoiPoints;
285  UpdateEdges();
286  }
287 
288  void UpdateEdges()
289  {
290  mEdges.clear();
291  int numPoints = mPoints.size();
292  for (int i = 0; i < numPoints; ++i)
293  mEdges.push_back(Edge(mPoints[i], mPoints[(i + 1) % numPoints]));
294  }
295 
297  bool PointIsInside(Eigen::Vector2d rPoint) const
298  {
299  int intersectionCounter = 0;
300  Eigen::Vector2d anyDirection(1., 0.);
301 
302  for (auto edge : mEdges)
303  if (edge.GetIntersectionLineParameter(rPoint, anyDirection) > 0.)
304  intersectionCounter++;
305 
306  return intersectionCounter % 2 == 1;
307  }
308 
310  bool SegmentIntersects(Eigen::Vector2d rP0, Eigen::Vector2d rP1) const
311  {
312  for (auto edge : mEdges)
313  {
314  double lineParameter = edge.GetIntersectionLineParameter(rP0, rP1 - rP0);
315  if (lineParameter > 0. and lineParameter < 1.)
316  return true;
317  }
318  return false;
319  }
320 
323  Eigen::Vector2d GetClosestIntersection(Eigen::Vector2d rPoint, Eigen::Vector2d rDirection) const
324  {
325  std::vector<Eigen::Vector2d> intersections;
326  double closestLineParameter = 1.e10;
327 
328  for (auto edge : mEdges)
329  {
330  double lineParameter = edge.GetIntersectionLineParameter(rPoint, rDirection);
331  if (lineParameter > 1.e-10)
332  closestLineParameter = std::min(closestLineParameter, lineParameter);
333  }
334  // if (closestLineParameter == 1.e10)
335  // throw "No intersection found!";
336 
337  return Eigen::Vector2d(rPoint + rDirection * closestLineParameter);
338  }
339 
341  int GetEdgeIndex(Eigen::Vector2d rPoint) const
342  {
343  for (unsigned int i = 0; i < mEdges.size(); ++i)
344  if (mEdges[i].GetDistance(rPoint) < 1.e-8)
345  return i;
346  return -1;
347  }
348 
350  Eigen::Vector2d GetPointOnBothEdges(int rEdge1, int rEdge2) const
351  {
352  auto e1 = mEdges[rEdge1];
353  auto e2 = mEdges[rEdge2];
354  if (e2.Contains(e1.P0()))
355  return e1.P0();
356  if (e2.Contains(e1.P1()))
357  return e1.P1();
358 
359  throw "There is no point on both rEdge1 and rEdge2";
360  }
361 
363  std::vector<Eigen::Vector2d> GetOtherPointsOnBoundary(Eigen::Vector2d rPoint) const
364  {
365  std::vector<Eigen::Vector2d> points = mPoints;
366  auto it = std::find(points.begin(), points.end(), rPoint);
367  assert(it != points.end());
368 
369  points.erase(it);
370  return points;
371  }
372 
376  void AddIntersectionWithBoundary(const Polygon& rBoundary, const Eigen::Vector2d& rIP)
377  {
378 
379  int numPointsOnBoundary = 0;
380  int numPoints = mPoints.size();
381 
382  for (auto vp : mPoints)
383  if (rBoundary.GetEdgeIndex(vp) != -1)
384  numPointsOnBoundary++;
385 
386  if (numPointsOnBoundary != 2)
387  return;
388 
389 
390  // may contain a boundary point
391  // needed if two neigboring points are on different boundary edges
392  for (int i = 0; i < numPoints; ++i)
393  {
394  int e0 = rBoundary.GetEdgeIndex(mPoints[i]);
395  int e1 = rBoundary.GetEdgeIndex(mPoints[(i + 1) % numPoints]);
396 
397  if (e0 == -1 || e1 == -1 || e0 == e1)
398  continue;
399 
400  auto boundaryPoint = rBoundary.GetPointOnBothEdges(e0, e1);
401 
402  // the boundaryPoint must be inside the voronoi cell
403  auto originalPoints = mPoints; // backup
404 
405  mPoints.push_back(boundaryPoint);
406  SortAndRemoveDoublicates();
407 
408  if (PointIsInside(rIP))
409  {
410  break; // since only one edge per voronoi polygon allowed
411  // normal case
412  }
413  else
414  {
415  std::cout << "This happens!" << std::endl;
416  // restore points
417  mPoints = originalPoints;
418 
419  auto otherBoundaryPoints = rBoundary.GetOtherPointsOnBoundary(boundaryPoint);
420  for (auto point : otherBoundaryPoints)
421  mPoints.push_back(point);
422 
423  SortAndRemoveDoublicates();
424  // if (not PointIsInside(rIP))
425  // throw "Damn it!";
426  }
427  }
428  }
429 
430 private:
431  std::vector<Edge> mEdges;
432  std::vector<Eigen::Vector2d> mPoints;
433 };
434 
435 
437 {
438 public:
439  DelaunayVoronoi(const std::vector<Eigen::Vector2d>& rPoints, bool rCalculateInTransformedSystem)
440  : mPoints(rPoints)
441  , mCalculateInTransformedSystem(rCalculateInTransformedSystem)
442  {
443  if (mCalculateInTransformedSystem)
444  Transform(mPoints);
445  }
446 
447  void SetBoundary(const std::vector<Eigen::Vector2d>& rBoundaryPoints)
448  {
449  auto points = rBoundaryPoints;
450  if (mCalculateInTransformedSystem)
451  Transform(points);
452 
453  mBoundary = Polygon(points);
454  }
455 
456  std::list<Triangle> GetDelaunayTriangulation()
457  {
458  if (mTriangulation.size() == 0)
459  CalculateDelaunayTriangulation();
460 
461  return mTriangulation;
462  }
463 
464  std::vector<Polygon> GetVoronoiCells()
465  {
466  if (mVoronoiPolygons.size() == 0)
467  CalculateVoronoiPolygons();
468 
469  return mVoronoiPolygons;
470  }
471 
472  void Transform(std::vector<Eigen::Vector2d>& rPoints)
473  {
474  Eigen::Matrix2d T;
475  T << 1, .5, 0, std::sqrt(0.75);
476 
477  for (auto& point : rPoints)
478  {
479  auto p = point;
480  point = T * p;
481  }
482  }
483 
484  void TransformInverse(std::vector<Eigen::Vector2d>& rPoints)
485  {
486  Eigen::Matrix2d T;
487  T << 1, .5, 0, std::sqrt(0.75);
488 
489  auto invT = T.inverse();
490 
491  for (auto& point : rPoints)
492  {
493  auto p = point;
494  point = invT * p;
495  }
496  }
497 
500  {
501  mTriangulation.clear();
502 
503  // define a super quad as two super triangles that contain all points and an offset
504  Eigen::Vector2d superMin = mPoints[0];
505  Eigen::Vector2d superMax = mPoints[0];
506  for (auto point : mPoints)
507  {
508  superMin = superMin.cwiseMin(point);
509  superMax = superMax.cwiseMax(point);
510  }
511 
512  auto size = superMax - superMin;
513  superMin -= 3 * size;
514  superMax += 3 * size;
515 
516  std::array<Eigen::Vector2d, 4> sP;
517  sP[0] = superMin;
518  sP[1] = Eigen::Vector2d(superMax.x(), superMin.y());
519  sP[2] = superMax;
520  sP[3] = Eigen::Vector2d(superMin.x(), superMax.y());
521 
522  mTriangulation.push_back(Triangle(Edge(sP[0], sP[1]), Edge(sP[1], sP[2]), Edge(sP[2], sP[0])));
523  mTriangulation.push_back(Triangle(Edge(sP[0], sP[2]), Edge(sP[2], sP[3]), Edge(sP[3], sP[0])));
524 
525 
526  // add every point from rPoints using the Bowyer–Watson algorithm
527  for (auto point : mPoints)
528  {
529  std::list<const Triangle*> badTriangles;
530  for (Triangle& triangle : mTriangulation)
531  {
532  if (triangle.CircumcircleContainsPoint(point))
533  badTriangles.push_back(&triangle);
534  }
535 
536  std::list<Edge> polygon;
537  for (const Triangle* badTriangle : badTriangles)
538  {
539  for (Edge edge : badTriangle->GetEdges())
540  {
541  bool edgeNotShared = true;
542  for (const Triangle* otherBadTriangle : badTriangles)
543  {
544  if (*otherBadTriangle == *badTriangle)
545  continue;
546 
547  if (otherBadTriangle->Contains(edge))
548  {
549  edgeNotShared = false;
550  break;
551  }
552  }
553  if (edgeNotShared)
554  polygon.push_back(edge);
555  }
556  }
557 
558  for (const Triangle* triangle : badTriangles)
559  mTriangulation.remove(*triangle);
560 
561  // create new edges containing the point
562  for (Edge edge : polygon)
563  mTriangulation.push_back(Triangle(edge, Edge(point, edge.P0()), Edge(point, edge.P1())));
564  }
565 
566  std::list<const Triangle*> trianglesToErase;
567 
568  // remove triangles containing the super points
569  for (Triangle& triangle : mTriangulation)
570  for (auto superPoint : sP)
571  if (triangle.Contains(superPoint))
572  trianglesToErase.push_back(&triangle);
573 
574  for (const Triangle* triangleToErase : trianglesToErase)
575  mTriangulation.remove(*triangleToErase);
576 
577 
578  std::ofstream file;
579  file.open("triangles.dat");
580  for (auto triangle : mTriangulation)
581  {
582  auto points = triangle.GetUniquePoints();
583  file << points[0].transpose() << '\n'
584  << points[1].transpose() << '\n'
585  << points[2].transpose() << '\n'
586  << points[0].transpose() << "\n \n";
587  }
588  file.close();
589  }
590 
591 
593  {
594  if (mBoundary.GetPoints().size() == 0)
595  throw "Define a the boundary first! [AddBoundary()]!";
596 
597  int num = mPoints.size();
598  mVoronoiPolygons.resize(num);
599 
600  if (mTriangulation.size() == 0)
601  CalculateDelaunayTriangulation();
602 
603 
604  struct EdgeHash
605  {
606  size_t operator()(const Edge& x) const
607  {
608  return x.GetHash();
609  }
610  };
611 
612  // create a data structure that contains all the triangles for every edge
613  std::unordered_map<Edge, std::vector<const Triangle*>, EdgeHash> edgeToTriangle;
614  for (const Triangle& triangle : mTriangulation)
615  for (Edge edge : triangle.GetEdges())
616  edgeToTriangle[edge].push_back(&triangle);
617 
618  for (int p = 0; p < num; ++p)
619  {
620  auto point = mPoints[p];
621 
622  std::list<Edge> edges;
623  for (auto pair : edgeToTriangle)
624  {
625  const Edge& edge = pair.first;
626  if (edge.Contains(point))
627  edges.push_back(edge);
628  }
629 
630  std::vector<Eigen::Vector2d> voronoiPoints;
631 
632  for (const Edge& edge : edges)
633  {
634  std::vector<const Triangle*> triangles = edgeToTriangle[edge];
635  assert(triangles.size() > 0);
636  assert(triangles.size() <= 2);
637 
638  Eigen::Vector2d p0, p1;
639 
640  if (triangles.size() == 1)
641  {
642 
643  p0 = triangles[0]->GetCircumcenter();
644 
645  // build a vector n from the circumcenter to its edge ...
646  Eigen::Vector2d e = edge.P1() - edge.P0();
647  Eigen::Vector2d edgePoint = edge.P0() + e.dot(p0 - edge.P0()) / e.dot(e) * e;
648  Eigen::Vector2d n = edgePoint - p0;
649 
650  // if the circumcenter lays on the edge, n is 0.
651  // instead pick any n perpendicular to e;
652 
653  if (std::abs(n.dot(n)) < 1.e-8)
654  n = Eigen::Vector2d(e[1], -e[0]);
655 
656  // For the special case of a circumcenter that is
657  // outside of its triangle and inside the boundary:
658  //
659  // a line l = p0 + t * n with t > 1 must not intersect
660  // any other edges of the triangle.
661  // if it does, reverse: n --> -n
662  bool intersectsAgain = false;
663 
664  for (Edge edgeTri : triangles[0]->GetEdges())
665  {
666  if (edgeTri == edge)
667  continue;
668 
669  double t = edgeTri.GetIntersectionLineParameter(p0, n);
670  if (t > 1.)
671  intersectsAgain = true;
672  }
673 
674  if (intersectsAgain)
675  n = -n;
676 
677  if (not mBoundary.PointIsInside(p0))
678  {
679 
680  if (intersectsAgain)
681  // do not consider the edge
682  // that intersects the triangle again
683  // oisch... sketches would help here... believe me please :)
684  continue;
685 
686  p0 = mBoundary.GetClosestIntersection(p0, n);
687  }
688  p1 = mBoundary.GetClosestIntersection(p0, n);
689  }
690 
691  if (triangles.size() == 2)
692  {
693  // find the point p0 in the boundary
694  p0 = triangles[0]->GetCircumcenter();
695  p1 = triangles[1]->GetCircumcenter();
696 
697  if (not mBoundary.PointIsInside(p0))
698  {
699  // if the line from p0 to p1 does not intersect
700  // the boundary, continue
701  if (not mBoundary.SegmentIntersects(p0, p1))
702  continue;
703 
704  // find p0 as closest intersection of p0 to p1
705  p0 = mBoundary.GetClosestIntersection(p0, p1 - p0);
706  }
707 
708  if (not mBoundary.PointIsInside(p1))
709  {
710  // find the intersection of the line p0-p1 with
711  // the boundary
712  p1 = mBoundary.GetClosestIntersection(p1, p0 - p1);
713  }
714  }
715 
716  voronoiPoints.push_back(p0);
717  voronoiPoints.push_back(p1);
718  }
719 
720  Polygon voronoiCell(voronoiPoints);
721  voronoiCell.AddIntersectionWithBoundary(mBoundary, point);
722  mVoronoiPolygons[p] = voronoiCell;
723  }
724  }
725 
726  void CalculateVisualizationCellsPolygon(std::vector<Eigen::Vector2d>& rVisuPoints,
727  std::vector<std::vector<unsigned int>>& rVisuCellIndices)
728  {
729  if (mVoronoiPolygons.size() == 0)
730  CalculateVoronoiPolygons();
731 
732  rVisuPoints.clear();
733  rVisuCellIndices.resize(mPoints.size());
734 
735  for (auto polygon : mVoronoiPolygons)
736  for (auto point : polygon.GetPoints())
737  if (std::find(rVisuPoints.begin(), rVisuPoints.end(), point) == rVisuPoints.end())
738  rVisuPoints.push_back(point);
739 
740  for (unsigned int iIP = 0; iIP < mPoints.size(); ++iIP)
741  {
742  auto polygon = mVoronoiPolygons[iIP];
743 
744  // perform a triangulation of the convex polygon
745  std::vector<unsigned int> visuCell;
746  for (auto vPoint : polygon.GetPoints())
747  // subtracting two iterators returns the index
748  visuCell.push_back(std::find(rVisuPoints.begin(), rVisuPoints.end(), vPoint) - rVisuPoints.begin());
749  rVisuCellIndices[iIP] = visuCell;
750  }
751 
752  if (mCalculateInTransformedSystem)
753  TransformInverse(rVisuPoints);
754  }
755 
761  void CalculateVisualizationCellsTriangle(std::vector<Eigen::Vector2d>& rVisuPoints,
762  std::vector<std::array<unsigned int, 3>>& rVisuCellIndices,
763  std::vector<unsigned int>& rCellIPIndex)
764  {
765  rVisuCellIndices.clear();
766  rCellIPIndex.clear();
767 
768  std::vector<std::vector<unsigned int>> polygonCells;
769  CalculateVisualizationCellsPolygon(rVisuPoints, polygonCells);
770  for (unsigned int iIP = 0; iIP < polygonCells.size(); ++iIP)
771  {
772  auto& polygon = polygonCells[iIP];
773 
774  unsigned int p0 = polygon[0];
775  // split each polygonCell in multiple triangle cells
776  for (unsigned int i = 1; i < polygon.size() - 1; ++i)
777  {
778  unsigned int p1 = polygon[i];
779  unsigned int p2 = polygon[i + 1];
780 
781  rVisuCellIndices.push_back({{p0, p1, p2}});
782  rCellIPIndex.push_back(iIP);
783  }
784  }
785  }
786 
787 
788 private:
789  std::vector<Eigen::Vector2d> mPoints;
790  std::list<Triangle> mTriangulation;
791  std::vector<Polygon> mVoronoiPolygons;
792  Polygon mBoundary;
793  bool mCalculateInTransformedSystem;
794 };
void CalculateVoronoiPolygons()
Definition: DelaunayVoronoi.h:592
bool PointIsInside(Eigen::Vector2d rPoint) const
counts the intersections with the edges. The point rPoint is inside the polygon if that number is odd...
Definition: DelaunayVoronoi.h:297
const NuTo::DofType d("...", 1)
void CalculateDelaunayTriangulation()
special thanks to https://en.wikipedia.org/wiki/Bowyer%E2%80%93Watson_algorithm
Definition: DelaunayVoronoi.h:499
void UpdateEdges()
Definition: DelaunayVoronoi.h:288
void CalculateVisualizationCellsPolygon(std::vector< Eigen::Vector2d > &rVisuPoints, std::vector< std::vector< unsigned int >> &rVisuCellIndices)
Definition: DelaunayVoronoi.h:726
Eigen::Vector2d GetCircumcenter() const
Definition: DelaunayVoronoi.h:166
bool operator==(const Triangle &rOther) const
Definition: DelaunayVoronoi.h:156
Eigen::Vector2d GetClosestIntersection(Eigen::Vector2d rPoint, Eigen::Vector2d rDirection) const
A line from rPoint in rDirection may intersect multiple times with the polygon.
Definition: DelaunayVoronoi.h:323
MeshFem Transform(MeshFem &&oldMesh, std::function< Eigen::VectorXd(Eigen::VectorXd)> f)
transforms a mesh with a given transformation function f
Definition: UnitMeshFem.cpp:117
Definition: DelaunayVoronoi.h:107
DelaunayVoronoi(const std::vector< Eigen::Vector2d > &rPoints, bool rCalculateInTransformedSystem)
Definition: DelaunayVoronoi.h:439
Triangle(Edge rE0, Edge rE1, Edge rE2)
Definition: DelaunayVoronoi.h:110
void Info() const
Definition: DelaunayVoronoi.h:222
double GetIntersectionLineParameter(const Eigen::Vector2d rPoint, const Eigen::Vector2d rDirection) const
returns the line parameter l of the line rPoint + l * rDirection where the line intersects with the e...
Definition: DelaunayVoronoi.h:75
Definition: DelaunayVoronoi.h:234
bool operator==(const Edge &rOther) const
Definition: DelaunayVoronoi.h:49
const Eigen::Vector2d P0() const
Definition: DelaunayVoronoi.h:39
Definition: DelaunayVoronoi.h:26
Eigen::Vector2d GetPointOnBothEdges(int rEdge1, int rEdge2) const
Returns a boundary point that is contained by both rEdge1 and rEdge2.
Definition: DelaunayVoronoi.h:350
const Eigen::Vector2d P1() const
Definition: DelaunayVoronoi.h:44
std::list< Triangle > GetDelaunayTriangulation()
Definition: DelaunayVoronoi.h:456
Definition: DelaunayVoronoi.h:436
void AddIntersectionWithBoundary(const Polygon &rBoundary, const Eigen::Vector2d &rIP)
add points to this polygon if it intersects with the boundary If the polygon contains two neighboring...
Definition: DelaunayVoronoi.h:376
void SetBoundary(const std::vector< Eigen::Vector2d > &rBoundaryPoints)
Definition: DelaunayVoronoi.h:447
void CalculateVisualizationCellsTriangle(std::vector< Eigen::Vector2d > &rVisuPoints, std::vector< std::array< unsigned int, 3 >> &rVisuCellIndices, std::vector< unsigned int > &rCellIPIndex)
calculates the polygon visualization cells and triangulates them again
Definition: DelaunayVoronoi.h:761
bool Contains(Edge rEdge) const
Definition: DelaunayVoronoi.h:148
void SortAndRemoveDoublicates()
Definition: DelaunayVoronoi.h:252
double GetDistance(Eigen::Vector2d rPoint) const
calculates the (perpendicular) distance of rPoint to the edge
Definition: DelaunayVoronoi.h:95
Polygon(std::vector< Eigen::Vector2d > rPoints)
Definition: DelaunayVoronoi.h:241
Polygon()
Definition: DelaunayVoronoi.h:237
bool Contains(const Eigen::Vector2d &rPoint) const
Definition: DelaunayVoronoi.h:140
Edge()
Definition: DelaunayVoronoi.h:29
std::vector< Polygon > GetVoronoiCells()
Definition: DelaunayVoronoi.h:464
size_t GetHash() const
Definition: DelaunayVoronoi.h:67
bool SegmentIntersects(Eigen::Vector2d rP0, Eigen::Vector2d rP1) const
returns true, if the polygon intersects the segment rP0-rP1
Definition: DelaunayVoronoi.h:310
void Info() const
Definition: DelaunayVoronoi.h:62
std::array< Eigen::Vector2d, 3 > GetUniquePoints() const
Definition: DelaunayVoronoi.h:117
void TransformInverse(std::vector< Eigen::Vector2d > &rPoints)
Definition: DelaunayVoronoi.h:484
void Transform(std::vector< Eigen::Vector2d > &rPoints)
Definition: DelaunayVoronoi.h:472
std::vector< Eigen::Vector2d > GetOtherPointsOnBoundary(Eigen::Vector2d rPoint) const
returns all mPoints except rPoint
Definition: DelaunayVoronoi.h:363
bool CircumcircleContainsPoint(const Eigen::Vector2d &rPoint) const
Definition: DelaunayVoronoi.h:181
std::vector< Eigen::Vector2d > GetPoints()
Definition: DelaunayVoronoi.h:247
Edge(Eigen::Vector2d rP0, Eigen::Vector2d rP1)
Definition: DelaunayVoronoi.h:33
const Eigen::MatrixBase< OtherDerived > abs() const
elementwise absolute value of the matrix
Definition: MatrixBaseAddons.h:17
std::array< Edge, 3 > GetEdges() const
Definition: DelaunayVoronoi.h:135
bool Contains(Eigen::Vector2d rPoint) const
Definition: DelaunayVoronoi.h:55
int GetEdgeIndex(Eigen::Vector2d rPoint) const
Returns the index of the edge that contains rPoint.
Definition: DelaunayVoronoi.h:341
int A
Definition: TimeIntegrationResultForce.py:7