Skip to content

Commit d221202

Browse files
committed
2 parents c139480 + 769f2ee commit d221202

File tree

1 file changed

+61
-29
lines changed

1 file changed

+61
-29
lines changed

DelaunatorSharp/Delaunator.cs

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public Delaunator(IPoint[] points)
4545
coords[2 * i + 1] = p.Y;
4646
}
4747

48-
var n = coords.Length >> 1;
48+
var n = points.Length;
4949
var maxTriangles = 2 * n - 5;
5050

5151
Triangles = new int[maxTriangles * 3];
@@ -384,7 +384,7 @@ private int Legalize(int a)
384384

385385
return ar;
386386
}
387-
private bool InCircle(double ax, double ay, double bx, double by, double cx, double cy, double px, double py)
387+
private static bool InCircle(double ax, double ay, double bx, double by, double cx, double cy, double px, double py)
388388
{
389389
var dx = ax - px;
390390
var dy = ay - py;
@@ -422,12 +422,12 @@ private void Link(int a, int b)
422422
if (b != -1) Halfedges[b] = a;
423423
}
424424
private int HashKey(double x, double y) => (int)(Math.Floor(PseudoAngle(x - cx, y - cy) * hashSize) % hashSize);
425-
private double PseudoAngle(double dx, double dy)
425+
private static double PseudoAngle(double dx, double dy)
426426
{
427427
var p = dx / (Math.Abs(dx) + Math.Abs(dy));
428428
return (dy > 0 ? 3 - p : 1 + p) / 4; // [0..1]
429429
}
430-
private void Quicksort(int[] ids, double[] dists, int left, int right)
430+
private static void Quicksort(int[] ids, double[] dists, int left, int right)
431431
{
432432
if (right - left <= 20)
433433
{
@@ -474,14 +474,14 @@ private void Quicksort(int[] ids, double[] dists, int left, int right)
474474
}
475475
}
476476
}
477-
private void Swap(int[] arr, int i, int j)
477+
private static void Swap(int[] arr, int i, int j)
478478
{
479479
var tmp = arr[i];
480480
arr[i] = arr[j];
481481
arr[j] = tmp;
482482
}
483-
private bool Orient(double px, double py, double qx, double qy, double rx, double ry) => (qy - py) * (rx - qx) - (qx - px) * (ry - qy) < 0;
484-
private double Circumradius(double ax, double ay, double bx, double by, double cx, double cy)
483+
private static bool Orient(double px, double py, double qx, double qy, double rx, double ry) => (qy - py) * (rx - qx) - (qx - px) * (ry - qy) < 0;
484+
private static double Circumradius(double ax, double ay, double bx, double by, double cx, double cy)
485485
{
486486
var dx = bx - ax;
487487
var dy = by - ay;
@@ -494,7 +494,7 @@ private double Circumradius(double ax, double ay, double bx, double by, double c
494494
var y = (dx * cl - ex * bl) * d;
495495
return x * x + y * y;
496496
}
497-
private Point Circumcenter(double ax, double ay, double bx, double by, double cx, double cy)
497+
private static Point Circumcenter(double ax, double ay, double bx, double by, double cx, double cy)
498498
{
499499
var dx = bx - ax;
500500
var dy = by - ay;
@@ -508,7 +508,7 @@ private Point Circumcenter(double ax, double ay, double bx, double by, double cx
508508

509509
return new Point(x, y);
510510
}
511-
private double Dist(double ax, double ay, double bx, double by)
511+
private static double Dist(double ax, double ay, double bx, double by)
512512
{
513513
var dx = ax - bx;
514514
var dy = ay - by;
@@ -558,29 +558,54 @@ public IEnumerable<IVoronoiCell> GetVoronoiCells(Func<int, IPoint> triangleVerti
558558
if (triangleVerticeSelector == null) triangleVerticeSelector = x => GetCentroid(x);
559559

560560
var seen = new HashSet<int>();
561+
var vertices = new List<IPoint>(10); // Keep it outside the loop, reuse capacity, less resizes.
562+
561563
for (var triangleId = 0; triangleId < Triangles.Length; triangleId++)
562564
{
563565
var id = Triangles[NextHalfedge(triangleId)];
564-
if (!seen.Any(x => x == id))
566+
// True if element was added, If resize the set? O(n) : O(1)
567+
if (seen.Add(id))
565568
{
566-
seen.Add(id);
567-
var edges = EdgesAroundPoint(triangleId);
568-
var triangles = edges.Select(x => TriangleOfEdge(x));
569-
var vertices = triangles.Select(triangleVerticeSelector).ToArray();
570-
yield return new VoronoiCell(id, vertices);
569+
foreach (var edge in EdgesAroundPoint(triangleId))
570+
{
571+
// triangleVerticeSelector cant be null, no need to check before invoke (?.).
572+
vertices.Add(triangleVerticeSelector.Invoke(TriangleOfEdge(edge)));
573+
}
574+
yield return new VoronoiCell(id, vertices.ToArray());
575+
vertices.Clear(); // Clear elements, keep capacity
571576
}
572577
}
573578
}
574579

575580
public IEnumerable<IVoronoiCell> GetVoronoiCellsBasedOnCircumcenters() => GetVoronoiCells(GetTriangleCircumcenter);
576581
public IEnumerable<IVoronoiCell> GetVoronoiCellsBasedOnCentroids() => GetVoronoiCells(GetCentroid);
577-
582+
578583
public IEnumerable<IEdge> GetHullEdges() => CreateHull(GetHullPoints());
579-
public IPoint[] GetHullPoints() => hull.Select(x => Points[x]).ToArray();
580-
public IPoint[] GetTrianglePoints(int t) => PointsOfTriangle(t).Select(p => Points[p]).ToArray();
581-
public IPoint[] GetRellaxedPoints() => GetVoronoiCellsBasedOnCircumcenters().Select(x => GetCentroid(x.Points)).ToArray();
584+
585+
public IPoint[] GetHullPoints() => Array.ConvertAll<int, IPoint>(hull, (x) => Points[x]);
586+
587+
public IPoint[] GetTrianglePoints(int t)
588+
{
589+
var points = new List<IPoint>();
590+
foreach (var p in PointsOfTriangle(t))
591+
{
592+
points.Add(Points[p]);
593+
}
594+
return points.ToArray();
595+
}
596+
597+
public IPoint[] GetRellaxedPoints()
598+
{
599+
var points = new List<IPoint>();
600+
foreach (var cell in GetVoronoiCellsBasedOnCircumcenters())
601+
{
602+
points.Add(GetCentroid(cell.Points));
603+
}
604+
return points.ToArray();
605+
}
606+
582607
public IEnumerable<IEdge> GetEdgesOfTriangle(int t) => CreateHull(EdgesOfTriangle(t).Select(p => Points[p]));
583-
public IEnumerable<IEdge> CreateHull(IEnumerable<IPoint> points) => points.Zip(points.Skip(1).Append(points.FirstOrDefault()), (a, b) => new Edge(0, a, b)).OfType<IEdge>();
608+
public static IEnumerable<IEdge> CreateHull(IEnumerable<IPoint> points) => points.Zip(points.Skip(1).Append(points.FirstOrDefault()), (a, b) => new Edge(0, a, b)).OfType<IEdge>();
584609
public IPoint GetTriangleCircumcenter(int t)
585610
{
586611
var vertices = GetTrianglePoints(t);
@@ -591,14 +616,15 @@ public IPoint GetCentroid(int t)
591616
var vertices = GetTrianglePoints(t);
592617
return GetCentroid(vertices);
593618
}
594-
public IPoint GetCircumcenter(IPoint a, IPoint b, IPoint c) => Circumcenter(a.X, a.Y, b.X, b.Y, c.X, c.Y);
595-
public IPoint GetCentroid(IPoint[] points)
619+
public static IPoint GetCircumcenter(IPoint a, IPoint b, IPoint c) => Circumcenter(a.X, a.Y, b.X, b.Y, c.X, c.Y);
620+
621+
public static IPoint GetCentroid(IPoint[] points)
596622
{
597623
double accumulatedArea = 0.0f;
598624
double centerX = 0.0f;
599625
double centerY = 0.0f;
600626

601-
for (int i = 0, j = points.Count() - 1; i < points.Count(); j = i++)
627+
for (int i = 0, j = points.Length - 1; i < points.Length; j = i++)
602628
{
603629
var temp = points[i].X * points[j].Y - points[j].X * points[i].Y;
604630
accumulatedArea += temp;
@@ -674,7 +700,13 @@ public IEnumerable<int> EdgesAroundPoint(int start)
674700
incoming = Halfedges[outgoing];
675701
} while (incoming != -1 && incoming != start);
676702
}
677-
public IEnumerable<int> PointsOfTriangle(int t) => EdgesOfTriangle(t).Select(e => Triangles[e]);
703+
public IEnumerable<int> PointsOfTriangle(int t)
704+
{
705+
foreach (var edge in EdgesOfTriangle(t))
706+
{
707+
yield return Triangles[edge];
708+
}
709+
}
678710
public IEnumerable<int> TrianglesAdjacentToTriangle(int t)
679711
{
680712
var adjacentTriangles = new List<int>();
@@ -690,10 +722,10 @@ public IEnumerable<int> TrianglesAdjacentToTriangle(int t)
690722
return adjacentTriangles;
691723
}
692724

693-
public int NextHalfedge(int e) => (e % 3 == 2) ? e - 2 : e + 1;
694-
public int PreviousHalfedge(int e) => (e % 3 == 0) ? e + 2 : e - 1;
695-
public int[] EdgesOfTriangle(int t) => new int[] { 3 * t, 3 * t + 1, 3 * t + 2 };
696-
public int TriangleOfEdge(int e) { return (int)Math.Floor((double)(e / 3)); }
725+
public static int NextHalfedge(int e) => (e % 3 == 2) ? e - 2 : e + 1;
726+
public static int PreviousHalfedge(int e) => (e % 3 == 0) ? e + 2 : e - 1;
727+
public static int[] EdgesOfTriangle(int t) => new int[] { 3 * t, 3 * t + 1, 3 * t + 2 };
728+
public static int TriangleOfEdge(int e) { return e / 3; }
697729
#endregion Methods based on index
698730
}
699-
}
731+
}

0 commit comments

Comments
 (0)