Added Convex Hull (chatgpt) - added DelayAsync to ChatGpt generated content
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user