コード例 #1
0
ファイル: VoronoiDiagram.cs プロジェクト: gmich/Gem
        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);
        }
コード例 #2
0
ファイル: VoronoiDiagram.cs プロジェクト: gmich/Gem
        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);
        }
コード例 #3
0
ファイル: VoronoiDiagram.cs プロジェクト: gmich/Gem
        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);
        }