public double GetXOfEdge(VoronoiParabola par, double y) { VoronoiParabola left = VoronoiParabola.GetLeftChild(par); VoronoiParabola right = VoronoiParabola.GetRightChild(par); Vector2 p = left.Site; Vector2 r = right.Site; double dp = 2.0 * (p.Y - y); double a1 = 1.0 / dp; double b1 = -2.0 * p.X / dp; double c1 = y + dp / 4 + p.X * p.X / dp; dp = 2.0 * (r.Y - y); double a2 = 1.0 / dp; double b2 = -2.0 * r.X / dp; double c2 = ly + dp / 4 + r.X * r.X / dp; double a = a1 - a2; double b = b1 - b2; double c = c1 - c2; double disc = b * b - 4 * a * c; double x1 = (-b + Math.Sqrt(disc)) / (2 * a); double x2 = (-b - Math.Sqrt(disc)) / (2 * a); double ry; if (p.Y < r.Y) { ry = Math.Max(x1, x2); } else { ry = Math.Min(x1, x2); } return(ry); }
public void CheckCircle(VoronoiParabola b) { VoronoiParabola lp = VoronoiParabola.GetLeftParent(b); VoronoiParabola rp = VoronoiParabola.GetRightParent(b); VoronoiParabola a = VoronoiParabola.GetLeftChild(lp); VoronoiParabola c = VoronoiParabola.GetRightChild(rp); if (a == null || c == null || a.Site == c.Site) { return; } Vector2 s = Vector2.Zero; s = GetEdgeIntersection(lp.Edge, rp.Edge); if (s == Vector2.Zero) { return; } double dx = a.Site.X - s.X; double dy = a.Site.Y - s.Y; double d = Math.Sqrt((dx * dx) + (dy * dy)); if (s.Y - d >= ly) { return; } VoronoiEvent e = new VoronoiEvent(new Vector2(s.X, s.Y - (float)d), false); points.Add(e.Position); b.CEvent = e; e.Arch = b; queue.Enqueue(e); }
public void RemoveParabola(VoronoiEvent e) { VoronoiParabola p1 = e.Arch; VoronoiParabola xl = VoronoiParabola.GetLeftParent(p1); VoronoiParabola xr = VoronoiParabola.GetRightParent(p1); VoronoiParabola p0 = VoronoiParabola.GetLeftChild(xl); VoronoiParabola p2 = VoronoiParabola.GetRightChild(xr); if (p0.CEvent != null) { deleted.Add(p0.CEvent); p0.CEvent = null; } if (p2.CEvent != null) { deleted.Add(p2.CEvent); p2.CEvent = null; } Vector2 p = new Vector2(e.Position.X, (float)GetY(p1.Site, e.Position.X)); points.Add(p); xl.Edge.End = p; xr.Edge.End = p; VoronoiParabola higher = null; VoronoiParabola par = p1; while (par != root) { par = par.Parent; if (par == xl) { higher = xl; } if (par == xr) { higher = xr; } } higher.Edge = new VoronoiEdge(p, p0.Site, p2.Site); Edges.Add(higher.Edge); VoronoiParabola gparent = p1.Parent.Parent; if (p1.Parent.Left == p1) { if (gparent.Left == p1.Parent) { gparent.Left = p1.Parent.Right; } if (gparent.Right == p1.Parent) { gparent.Right = p1.Parent.Right; } } else { if (gparent.Left == p1.Parent) { gparent.Left = p1.Parent.Left; } if (gparent.Right == p1.Parent) { gparent.Right = p1.Parent.Left; } } CheckCircle(p0); CheckCircle(p2); }