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)
|
||||
{
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user