public void PlotTriple(Site s1, Site s2, Site s3) { if (Debug) { Console.WriteLine("triple {0} {1} {2}", s1, s2, s3); } var triangle = new Triangle(s1, s2, s3) { New = true }; Triangles.Add(triangle); }
public void PlotVertex(Site s) { if (Debug) { Console.WriteLine("vertex {0},{1}", s.X, s.Y); Log.InfoFormat("vertex {0},{1}", s.X, s.Y); } s.New = true; Vertices.Add(s); }
public static int CompareByYThenX(Site s1, ICoord s2) { if (s1.Y < s2.Y) return -1; if (s1.Y > s2.Y) return 1; if (s1.X < s2.X) return -1; if (s1.X > s2.X) return 1; return 0; }
public void PlotSite(Site site) { site.New = true; Sites.Add(site); if (Debug) { Console.WriteLine("site {0}", site); Log.InfoFormat("site {0}", site); } if (site.Y > SweepLine) { SweepLine = site.Y; } }
public static bool RightOf(HalfEdge he, Site p) { var e = he.Edge; var topSite = e.Region[Side.Right]; var rightOfSite = (p.X > topSite.X); if (rightOfSite && (he.Side == Side.Left)) { return true; } if (!rightOfSite && (he.Side == Side.Right)) { return false; } bool above; if (Math.Abs(e.A - 1) < Tolerance) { var dyp = p.Y - topSite.Y; var dxp = p.X - topSite.X; var fast = false; if ((!rightOfSite && (e.B < 0)) || (rightOfSite && (e.B >= 0))) { above = fast = (dyp >= e.B*dxp); } else { above = ((p.X + p.Y*e.B) > e.C); if (e.B < 0) { above = !above; } if (!above) { fast = true; } } if (!fast) { var dxs = topSite.X - e.Region[Side.Left].X; above = (e.B*(dxp*dxp - dyp*dyp)) < (dxs*dyp*(1 + 2*dxp/dxs + e.B*e.B)); if (e.B < 0) { above = !above; } } } else { // e.b == 1 var y1 = e.C - e.A*p.X; var t1 = p.Y - y1; var t2 = p.X - topSite.X; var t3 = y1 - topSite.Y; above = (t1*t1) > (t2*t2 + t3*t3); } return he.Side == Side.Left ? above : !above; }
public static Edge Bisect(Site s1, Site s2) { var newEdge = new Edge(s1, s2); var dx = s2.X - s1.X; var dy = s2.Y - s1.Y; var adx = dx > 0 ? dx : -dx; var ady = dy > 0 ? dy : -dy; newEdge.C = s1.X * dx + s1.Y * dy + (dx * dx + dy * dy) * 0.5f; if (adx > ady) { newEdge.A = 1; newEdge.B = dy / dx; newEdge.C /= dx; } else { newEdge.B = 1; newEdge.A = dx / dy; newEdge.C /= dy; } return newEdge; }
public static Site Intersect(HalfEdge el1, HalfEdge el2) { var e1 = el1.Edge; var e2 = el2.Edge; if (e1 == null || e2 == null) { return null; } if (e1.Region[Side.Right] == e2.Region[Side.Right]) { return null; } var d = (e1.A*e2.B) - (e1.B*e2.A); if (Math.Abs(d) < Tolerance) { return null; } var xint = (e1.C*e2.B - e2.C*e1.B)/d; var yint = (e2.C*e1.A - e1.C*e2.A)/d; var e1Region = e1.Region[Side.Right]; var e2Region = e2.Region[Side.Right]; HalfEdge el; Edge e; if ((e1Region.Y < e2Region.Y) || Math.Abs(e1Region.Y - e2Region.Y) < Tolerance && e1Region.X < e2Region.X) { el = el1; e = e1; } else { el = el2; e = e2; } var rightOfSite = (xint >= e.Region[Side.Right].X); if ((rightOfSite && (el.Side == Side.Left)) || (!rightOfSite && (el.Side == Side.Right))) { return null; } var vertex = new Site(xint, yint); //vertex.AddEdge(e1); //vertex.AddEdge(e2); return vertex; }
public Triangle(Site s1, Site s2, Site s3) { V1 = s1; V2 = s2; V3 = s3; }
public Segment(Site p1, Site p2) { P1 = p1; P2 = p2; }
private void AddSite(Vector2 p, Color4 color, int index) { if (_sitesIndexedByLocation.ContainsKey(p)) return; var weight = MathF.Rand(0, 1.0f) * 100; var site = new Site(p, index, weight, color); _sites.Push(site); _sitesIndexedByLocation[p] = site; }
private void ClipLine(Edge e) { var dy = Height; var dx = Width; var d = (dx > dy) ? dx : dy; var pxMin = -(d - dx) / 2; var pxMax = Width + (d - dx) / 2; var pyMin = -(d - dy) / 2; var pyMax = Height + (d - dy) / 2; Site s1, s2; float x1, x2, y1, y2; Side side; if (Math.Abs(e.A - 1) < Geometry.Tolerance && e.B >= 0) { side = Side.Right; s1 = e.Endpoint[Side.Right]; s2 = e.Endpoint[Side.Left]; } else { side = Side.Left; s1 = e.Endpoint[Side.Left]; s2 = e.Endpoint[Side.Right]; } if (s1 != null && s2 != null) { if ((s1.Y < pyMin && s2.Y > pyMax) || (s1.Y > pyMax && s2.Y < pyMin)) { return; } } if (Math.Abs(e.A - 1) < Geometry.Tolerance) { y1 = pyMin; if (s1 != null && s1.Y > pyMin) { y1 = s1.Y; } if (y1 > pyMax) { return; } x1 = e.C - e.B * y1; y2 = pyMax; if (s2 != null && s2.Y < pyMax) { y2 = s2.Y; } if (y2 < pyMin) { return; } x2 = e.C - e.B * y2; if (((x1 > pxMax) && (x2 > pxMax)) || ((x1 < pxMin) && (x2 < pxMin))) { return; } if (x1 > pxMax) { x1 = pxMax; y1 = (e.C - x1) / e.B; } if (x1 < pxMin) { x1 = pxMin; y1 = (e.C - x1) / e.B; } if (x2 > pxMax) { x2 = pxMax; y2 = (e.C - x2) / e.B; } if (x2 < pxMin) { x2 = pxMin; y2 = (e.C - x2) / e.B; } } else { x1 = pxMin; if (s1 != null && s1.X > pxMin) { x1 = s1.X; } if (x1 > pxMax) { return; } y1 = e.C - e.A * x1; x2 = pxMax; if (s2 != null && s2.X < pxMax) { x2 = s2.X; } if (x2 < pxMin) { return; } y2 = e.C - e.A * x2; if (((y1 > pyMax) && (y2 > pyMax)) || ((y1 < pyMin) && (y2 < pyMin))) { return; } if (y1 > pyMax) { y1 = pyMax; x1 = (e.C - y1) / e.A; } if (y1 < pyMin) { y1 = pyMin; x1 = (e.C - y1) / e.A; } if (y2 > pyMax) { y2 = pyMax; x2 = (e.C - y2) / e.A; } if (y2 < pyMin) { y2 = pyMin; x2 = (e.C - y2) / e.A; } } var p1 = new PointF(x1, y1); var p2 = new PointF(x2, y2); var clipped = CohenSutherland.ClipSegment(new RectangleF(0,0, Width, Height), p1, p2 ); if (clipped != null) { var site1 = new Site(clipped.Item1); var site2 = new Site(clipped.Item2); var s = new Segment(site1, site2) { New = true }; Segments.Add(s); /*if (s1 == null) { e.Endpoint[side] = site1; } if (s2 == null) { e.Endpoint[Side.Other(side)] = site2; }*/ } }
public static float Distance(Site s, Site t) { var dx = s.X - t.X; var dy = s.Y - t.Y; return (float) Math.Sqrt(dx*dx + dy*dy); }
public static void EndPoint(Edge edge, Side side, Site site, VoronoiGraph c) { edge.Endpoint[side] = site; var opSide = side == Side.Left ? Side.Right : Side.Left; if (edge.Endpoint[opSide] == null) { return; } c.PlotEndpoint(edge); }