Added Convex Hull (chatgpt) - added DelayAsync to ChatGpt generated content

This commit is contained in:
Ano-sys
2025-11-04 22:29:25 +01:00
parent 03414ff88f
commit 19f8b2e651
@@ -227,12 +227,14 @@ public partial class MainWindowViewModel : ViewModelBase
return $"{Q(ax)},{Q(ay)}|{Q(bx)},{Q(by)}"; return $"{Q(ax)},{Q(ay)}|{Q(bx)},{Q(by)}";
} }
void DrawCircles(IEnumerable<Geometries.Triangle> triangles, Geometries.Point superA, Geometries.Point superB, async Task DrawCircles(CancellationToken ct, IEnumerable<Geometries.Triangle> triangles, Geometries.Point superA, Geometries.Point superB,
Geometries.Point superC) Geometries.Point superC)
{ {
Circles.Clear(); Circles.Clear();
foreach (var t in triangles) foreach (var t in triangles)
{ {
ct.ThrowIfCancellationRequested();
if (UsesVertex(t, superA) || UsesVertex(t, superB) || UsesVertex(t, superC)) continue; if (UsesVertex(t, superA) || UsesVertex(t, superB) || UsesVertex(t, superC)) continue;
try try
{ {
@@ -242,7 +244,10 @@ public partial class MainWindowViewModel : ViewModelBase
var cc = new Geometries.Circle(a, b, c); var cc = new Geometries.Circle(a, b, c);
if (double.IsFinite(cc.X) && double.IsFinite(cc.Y) && double.IsFinite(cc.R) && cc.R > 0) if (double.IsFinite(cc.X) && double.IsFinite(cc.Y) && double.IsFinite(cc.R) && cc.R > 0)
{
Circles.Add(cc); Circles.Add(cc);
await DelayAsync(ct);
}
} }
catch (ArgumentException) catch (ArgumentException)
{ {
@@ -250,13 +255,15 @@ public partial class MainWindowViewModel : ViewModelBase
} }
} }
void BuildVoronoi(Geometries.Point sa, Geometries.Point sb, Geometries.Point sc) async Task BuildVoronoi(CancellationToken ct, Geometries.Point sa, Geometries.Point sb, Geometries.Point sc)
{ {
VoronoiDiagram.Clear(); VoronoiDiagram.Clear();
var center = new Dictionary<Geometries.Triangle, (double x, double y)>(); var center = new Dictionary<Geometries.Triangle, (double x, double y)>();
foreach (var t in Triangles) foreach (var t in Triangles)
{ {
ct.ThrowIfCancellationRequested();
if (UsesVertex(t, sa) || UsesVertex(t, sb) || UsesVertex(t, sc)) continue; if (UsesVertex(t, sa) || UsesVertex(t, sb) || UsesVertex(t, sc)) continue;
try try
{ {
@@ -274,6 +281,8 @@ public partial class MainWindowViewModel : ViewModelBase
var map = new Dictionary<string, (Geometries.Edge edge, List<Geometries.Triangle> tris)>(); var map = new Dictionary<string, (Geometries.Edge edge, List<Geometries.Triangle> tris)>();
foreach (var t in Triangles) foreach (var t in Triangles)
{ {
ct.ThrowIfCancellationRequested();
if (UsesVertex(t, sa) || UsesVertex(t, sb) || UsesVertex(t, sc)) continue; if (UsesVertex(t, sa) || UsesVertex(t, sb) || UsesVertex(t, sc)) continue;
foreach (var e in ExtractTriangleEdges(t)) foreach (var e in ExtractTriangleEdges(t))
{ {
@@ -287,11 +296,16 @@ public partial class MainWindowViewModel : ViewModelBase
var far = 10 * Math.Max(Width, Height); var far = 10 * Math.Max(Width, Height);
foreach (var kv in map.Values) foreach (var kv in map.Values)
{ {
ct.ThrowIfCancellationRequested();
var e = kv.edge; var e = kv.edge;
var tris = kv.tris; var tris = kv.tris;
if (tris.Count == 2 && center.TryGetValue(tris[0], out var c0) && center.TryGetValue(tris[1], out var c1)) if (tris.Count == 2 && center.TryGetValue(tris[0], out var c0) && center.TryGetValue(tris[1], out var c1))
{
VoronoiDiagram.Add(new Geometries.Edge(c0.x, c0.y, c1.x, c1.y)); VoronoiDiagram.Add(new Geometries.Edge(c0.x, c0.y, c1.x, c1.y));
await DelayAsync(ct);
}
else if (tris.Count == 1 && center.TryGetValue(tris[0], out var c)) else if (tris.Count == 1 && center.TryGetValue(tris[0], out var c))
{ {
@@ -320,10 +334,57 @@ public partial class MainWindowViewModel : ViewModelBase
} }
VoronoiDiagram.Add(new Geometries.Edge(c.x, c.y, c.x + nx * far, c.y + ny * far)); VoronoiDiagram.Add(new Geometries.Edge(c.x, c.y, c.x + nx * far, c.y + ny * far));
await DelayAsync(ct);
} }
} }
} }
static double Cross(Geometries.Point o, Geometries.Point a, Geometries.Point b) =>
(a.X - o.X) * (b.Y - o.Y) - (a.Y - o.Y) * (b.X - o.X);
List<Geometries.Point> ComputeConvexHull(IList<Geometries.Point> pts)
{
if (pts.Count <= 1) return pts.ToList();
var p = pts.OrderBy(x => x.X).ThenBy(x => x.Y).ToList();
var lower = new List<Geometries.Point>();
foreach (var pt in p)
{
while (lower.Count >= 2 && Cross(lower[^2], lower[^1], pt) <= 0) lower.RemoveAt(lower.Count - 1);
lower.Add(pt);
}
var upper = new List<Geometries.Point>();
for (int i = p.Count - 1; i >= 0; i--)
{
var pt = p[i];
while (upper.Count >= 2 && Cross(upper[^2], upper[^1], pt) <= 0) upper.RemoveAt(upper.Count - 1);
upper.Add(pt);
}
lower.RemoveAt(lower.Count - 1);
upper.RemoveAt(upper.Count - 1);
return lower.Concat(upper).ToList();
}
async Task DrawConvexHull(CancellationToken ct)
{
Edges.Clear();
var hull = ComputeConvexHull(Points);
if (hull.Count < 2) return;
for (int i = 0; i < hull.Count; i++)
{
ct.ThrowIfCancellationRequested();
var a = hull[i];
var b = hull[(i + 1) % hull.Count];
Edges.Add(new Geometries.Edge(a.X, a.Y, b.X, b.Y));
await DelayAsync(ct);
}
}
async Task BowyerWatson(CancellationToken ct) async Task BowyerWatson(CancellationToken ct)
{ {
Triangles.Clear(); Triangles.Clear();
@@ -351,8 +412,7 @@ public partial class MainWindowViewModel : ViewModelBase
} }
} }
DrawCircles(bad, sa, sb, sc); await DrawCircles(ct, bad, sa, sb, sc);
await DelayAsync(ct);
var edgeCount = new Dictionary<string, Geometries.Edge>(); var edgeCount = new Dictionary<string, Geometries.Edge>();
var counter = new Dictionary<string, int>(); var counter = new Dictionary<string, int>();
@@ -391,11 +451,9 @@ public partial class MainWindowViewModel : ViewModelBase
var toRemove = Triangles.Where(t => UsesVertex(t, sa) || UsesVertex(t, sb) || UsesVertex(t, sc)).ToList(); var toRemove = Triangles.Where(t => UsesVertex(t, sa) || UsesVertex(t, sb) || UsesVertex(t, sc)).ToList();
foreach (var t in toRemove) Triangles.Remove(t); foreach (var t in toRemove) Triangles.Remove(t);
DrawCircles(Triangles, sa, sb, sc); await DrawCircles(ct, Triangles, sa, sb, sc);
await DelayAsync(ct); await BuildVoronoi(ct, sa, sb, sc);
await DrawConvexHull(ct);
BuildVoronoi(sa, sb, sc);
await DelayAsync(ct);
} }
async Task DelaunayTriangulateAsync(CancellationToken ct) async Task DelaunayTriangulateAsync(CancellationToken ct)