From 982ee0903404ee8e6c78ffb73d43406e6db37952 Mon Sep 17 00:00:00 2001 From: Ano-sys Date: Tue, 4 Nov 2025 22:15:51 +0100 Subject: [PATCH] add voronoi and circles (chatgpt) --- .../ViewModels/MainWindowViewModel.cs | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/DelauneyTriangulation/ViewModels/MainWindowViewModel.cs b/DelauneyTriangulation/ViewModels/MainWindowViewModel.cs index ff73718..6affe9a 100644 --- a/DelauneyTriangulation/ViewModels/MainWindowViewModel.cs +++ b/DelauneyTriangulation/ViewModels/MainWindowViewModel.cs @@ -250,6 +250,80 @@ public partial class MainWindowViewModel : ViewModelBase } } + void BuildVoronoi(Geometries.Point sa, Geometries.Point sb, Geometries.Point sc) + { + VoronoiDiagram.Clear(); + + var center = new Dictionary(); + foreach (var t in Triangles) + { + if (UsesVertex(t, sa) || UsesVertex(t, sb) || UsesVertex(t, sc)) continue; + try + { + var cc = new Geometries.Circle( + new Geometries.Point(t.X.X, t.X.Y), + new Geometries.Point(t.Y.X, t.Y.Y), + new Geometries.Point(t.Z.X, t.Z.Y)); + center[t] = (cc.X, cc.Y); + } + catch (ArgumentException) + { + } + } + + var map = new Dictionary tris)>(); + foreach (var t in Triangles) + { + if (UsesVertex(t, sa) || UsesVertex(t, sb) || UsesVertex(t, sc)) continue; + foreach (var e in ExtractTriangleEdges(t)) + { + var k = CanonKey(e); + if (!map.TryGetValue(k, out var val)) val = (e, new List()); + val.tris.Add(t); + map[k] = val; + } + } + + var far = 10 * Math.Max(Width, Height); + foreach (var kv in map.Values) + { + var e = kv.edge; + var tris = kv.tris; + + 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)); + + else if (tris.Count == 1 && center.TryGetValue(tris[0], out var c)) + { + double ex = e.X2 - e.X1, ey = e.Y2 - e.Y1; + double nx = -ey, ny = ex; + var nlen = Math.Sqrt(nx * nx + ny * ny); + + if (nlen > 0) + { + nx /= nlen; + ny /= nlen; + } + + var mx = 0.5 * (e.X1 + e.X2); + var my = 0.5 * (e.Y1 + e.Y2); + + var t = tris[0]; + var cx = (t.X.X + t.Y.X + t.Z.X) / 3.0; + var cy = (t.X.Y + t.Y.Y + t.Z.Y) / 3.0; + var dot = (cx - mx) * nx + (cy - my) * ny; + + if (dot > 0) + { + nx = -nx; + ny = -ny; + } + + VoronoiDiagram.Add(new Geometries.Edge(c.x, c.y, c.x + nx * far, c.y + ny * far)); + } + } + } + async Task BowyerWatson(CancellationToken ct) { Triangles.Clear(); @@ -324,6 +398,9 @@ public partial class MainWindowViewModel : ViewModelBase DrawCircles(Triangles, sa, sb, sc); await DelayAsync(ct); + + BuildVoronoi(sa, sb, sc); + await DelayAsync(ct); } async Task DelaunayTriangulateAsync(CancellationToken ct)