add voronoi and circles (chatgpt)
This commit is contained in:
@@ -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<Geometries.Triangle, (double x, double y)>();
|
||||||
|
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<string, (Geometries.Edge edge, List<Geometries.Triangle> 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<Geometries.Triangle>());
|
||||||
|
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)
|
async Task BowyerWatson(CancellationToken ct)
|
||||||
{
|
{
|
||||||
Triangles.Clear();
|
Triangles.Clear();
|
||||||
@@ -324,6 +398,9 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
|
|
||||||
DrawCircles(Triangles, sa, sb, sc);
|
DrawCircles(Triangles, sa, sb, sc);
|
||||||
await DelayAsync(ct);
|
await DelayAsync(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