Exemplo n.º 1
0
 //Added by Dozed
 internal VEdge(VPoint start, VPoint end, FortuneSite left, FortuneSite right)
 {
     Start = start;
     End   = end;
     Left  = left;
     Right = right;
 }
Exemplo n.º 2
0
        public void Initialize(VPoint start, FortuneSite left, FortuneSite right)
        {
            Start     = start;
            End       = VPoint.Default;
            Left      = left;
            Right     = right;
            IsClipped = false;
            Neighbor  = null;

            //for bounding box edges
            if (left == null || right == null)
            {
                return;
            }

            //from negative reciprocal of slope of line from left to right
            //ala m = (left.y -right.y / left.x - right.x)
            SlopeRise = left.X - right.X;
            SlopeRun  = -(left.Y - right.Y);
            Intercept = null;

            if (SlopeRise.ApproxEqual(0) || SlopeRun.ApproxEqual(0))
            {
                return;
            }
            Slope     = SlopeRise / SlopeRun;
            Intercept = start.Y - Slope * start.X;
        }
Exemplo n.º 3
0
 public Vector2Edge(Vector2X Start, Vector2X End, FortuneSite Left, FortuneSite Right)
 {
     start = Start;
     end   = End;
     left  = Left;
     right = Right;
 }
Exemplo n.º 4
0
        private void DrawPoint(SpriteBatch sb, FortuneSite point)
        {
            var size = 5;
            var rect = new Rectangle((int)(point.X - size / 2.0), (int)(point.Y - size / 2.0), size, size);

            sb.Draw(t, rect, Color.Green);
        }
Exemplo n.º 5
0
        internal VEdge(VPoint start, FortuneSite left, FortuneSite right)
        {
            Start = start;
            Left  = left;
            Right = right;

            //for bounding box edges
            if (left == null || right == null)
            {
                return;
            }

            //from negative reciprocal of slope of line from left to right
            //ala m = (left.y -right.y / left.x - right.x)
            SlopeRise = left.X - right.X;
            SlopeRun  = -(left.Y - right.Y);
            Intercept = null;

            if (SlopeRise.ApproxEqual(0) || SlopeRun.ApproxEqual(0))
            {
                return;
            }
            Slope     = SlopeRise / SlopeRun;
            Intercept = start.Y - Slope * start.X;
        }
Exemplo n.º 6
0
        private static HashSet <Point> FindVertices(FortuneSite Site) //finds all the vertices needed.
        {
            HashSet <Point> set = new HashSet <Point>();

            foreach (VEdge edge in Site.Cell)
            {
                set.Add(edge.Start);
                set.Add(edge.End);
            }
            return(set);
        }
Exemplo n.º 7
0
    private static void CheckCircle(RedBlackTreeNode <BeachSection> section, MinHeap <FortuneEvent> eventQueue)
    {
        RedBlackTreeNode <BeachSection> left  = section.previous;
        RedBlackTreeNode <BeachSection> right = section.next;

        if (left == null || right == null)
        {
            return;
        }

        FortuneSite leftSite   = left.data.site;
        FortuneSite centerSite = section.data.site;
        FortuneSite rightSite  = right.data.site;

        if (leftSite == rightSite)
        {
            return;
        }


        double bX = centerSite.x;
        double bY = centerSite.y;
        double aX = leftSite.x - bX;
        double aY = leftSite.y - bY;
        double cX = rightSite.x - bX;
        double cY = rightSite.y - bY;

        double delta = aX * cY - aY * cX;

        if (delta.ApproxGreaterThanOrEqualTo(0))
        {
            return;
        }

        double magnitudeA = aX * aX + aY * aY;
        double magnitudeC = cX * cX + cY * cY;

        double x = (cY * magnitudeA - aY * magnitudeC) / (2 * delta);
        double y = (aX * magnitudeC - cX * magnitudeA) / (2 * delta);

        double yCenter = y + bY;

        FortuneCircleEvent circleEvent = new FortuneCircleEvent(
            new Point(x + bX, yCenter + Math.Sqrt(x * x + y * y)),
            yCenter, section
            );

        section.data.circleEvent = circleEvent;
        eventQueue.Insert(circleEvent);
    }
Exemplo n.º 8
0
        private void DrawPoint(SpriteBatch sb, FortuneSite point)
        {
            var size = 5;
            var rect = new Rectangle((int)(point.X - size / 2.0), (int)(point.Y - size / 2.0), size, size);

            var color = Color.Green;

            if (testPoint != null && point.Contains(testPoint))
            {
                color = Color.Red;
            }

            sb.Draw(t, rect, color);
        }
Exemplo n.º 9
0
    public Edge(Point start, FortuneSite left, FortuneSite right)
    {
        this.start = start;
        this.left  = left;
        this.right = right;

        if (this.left == null || this.right == null)
        {
            return;
        }

        this.slopeRise = this.left.x - this.right.x;
        this.slopeRun  = -(this.left.y - this.right.y);

        if (this.slopeRise.ApproxEqual(0) || this.slopeRun.ApproxEqual(0))
        {
            return;
        }

        this.slope     = this.slopeRise / this.slopeRun;
        this.intercept = this.start.y - this.slope * this.start.x;
    }
Exemplo n.º 10
0
        private static Point Compute2DCentroid(FortuneSite Site) //computes centroid to do Loyd Algorithm
        {
            var vertices = FindVertices(Site).ToArray();

            if (!(vertices.Length - 1 > 0))
            {
                return(Site.point);
            }
            double Area     = 0;
            Point  Centroid = new Point(0, 0);

            int i = 0;

            for (; i < vertices.Count() - 1; i++)
            {
                Point current     = vertices[i];
                Point next        = vertices[i + 1];
                var   partialarea = current.X * next.Y - next.X * current.Y;
                Area       += partialarea;
                Centroid.X += (current.X + next.X) * partialarea;
                Centroid.Y += (current.Y + next.Y) * partialarea;
            }

            var last        = vertices[i];
            var first       = vertices[0];
            var partialArea = last.X * first.Y - first.X * last.Y;

            Area       += partialArea;
            Centroid.X += (first.X + last.X) * partialArea;
            Centroid.Y += (first.Y + last.Y) * partialArea;

            Area       *= 0.5;
            Centroid.X /= (6.0 * Area);
            Centroid.Y /= (6.0 * Area);

            return(Centroid);
        }
Exemplo n.º 11
0
    private static double LeftBreakpoint(RedBlackTreeNode <BeachSection> node, double directrix)
    {
        RedBlackTreeNode <BeachSection> leftNode = node.previous;

        if ((node.data.site.y - directrix).ApproxEqual(0))
        {
            return(node.data.site.x);
        }

        if (leftNode == null)
        {
            return(double.NegativeInfinity);
        }

        if ((leftNode.data.site.y - directrix).ApproxEqual(0))
        {
            return(leftNode.data.site.x);
        }

        FortuneSite site     = node.data.site;
        FortuneSite leftSite = leftNode.data.site;

        return(ParabolaMath.IntersectParabola(leftSite.x, leftSite.y, site.x, site.y, directrix));
    }
Exemplo n.º 12
0
    private static double RightBreakpoint(RedBlackTreeNode <BeachSection> node, double directrix)
    {
        RedBlackTreeNode <BeachSection> rightNode = node.next;

        if ((node.data.site.y - directrix).ApproxEqual(0))
        {
            return(node.data.site.x);
        }

        if (rightNode == null)
        {
            return(double.PositiveInfinity);
        }

        if ((rightNode.data.site.y - directrix).ApproxEqual(0))
        {
            return(rightNode.data.site.x);
        }

        FortuneSite site      = node.data.site;
        FortuneSite rightSite = rightNode.data.site;

        return(ParabolaMath.IntersectParabola(site.x, site.y, rightSite.x, rightSite.y, directrix));
    }
Exemplo n.º 13
0
        private static VEdge AddEdgeForBoundingBox(VPoint startPoint, VPoint otherPoint, FortuneSite site, bool left)
        {
            var newEdge = new VEdge(startPoint, left ? site : null, left ? null : site)
            {
                End = otherPoint
            };

            site.Cell.Add(newEdge);
            return(newEdge);
        }
Exemplo n.º 14
0
 public FortuneSiteEvent(FortuneSite site)
 {
     this.site = site;
 }
Exemplo n.º 15
0
 internal FortuneSiteEvent(FortuneSite site)
 {
     Site = site;
 }
Exemplo n.º 16
0
 public BeachSection(FortuneSite site)
 {
     this.site        = site;
     this.circleEvent = null;
 }
Exemplo n.º 17
0
    public void AddSection(FortuneSiteEvent siteEvent, MinHeap <FortuneEvent> eventQueue, HashSet <FortuneCircleEvent> deleted, LinkedList <Edge> edges)
    {
        FortuneSite site      = siteEvent.site;
        double      x         = site.x;
        double      directrix = site.y;

        RedBlackTreeNode <BeachSection> leftSection  = null;
        RedBlackTreeNode <BeachSection> rightSection = null;
        RedBlackTreeNode <BeachSection> root         = sections.root;

        while (root != null && leftSection != null && rightSection != null)
        {
            double distanceLeft = LeftBreakpoint(root, directrix) - x;
            if (distanceLeft > 0)
            {
                if (root.left == null)
                {
                    rightSection = root;
                }
                else
                {
                    root = root.left;
                }

                continue;
            }

            double distanceRight = x - RightBreakpoint(root, directrix);
            if (distanceRight > 0)
            {
                if (root.right == null)
                {
                    leftSection = root;
                }
                root = root.right;

                continue;
            }

            if (distanceLeft.ApproxEqual(0))
            {
                leftSection  = root.previous;
                rightSection = root;
                continue;
            }

            if (distanceRight.ApproxEqual(0))
            {
                leftSection  = root;
                rightSection = root.next;
                continue;
            }

            leftSection = rightSection = root;
        }

        BeachSection section = new BeachSection(site);
        RedBlackTreeNode <BeachSection> newSectionNode = sections.Insert(leftSection, section);

        if (leftSection == null && rightSection == null)
        {
            return;
        }

        if (leftSection != null && leftSection == rightSection)
        {
            if (leftSection.data.circleEvent != null)
            {
                deleted.Add(leftSection.data.circleEvent);
                leftSection.data.circleEvent = null;
            }

            BeachSection copy = new BeachSection(leftSection.data.site);
            rightSection = sections.Insert(newSectionNode, copy);

            double y            = ParabolaMath.EvalParabola(leftSection.data.site.x, leftSection.data.site.y, directrix, x);
            Point  intersection = new Point(x, y);

            Edge leftEdge  = new Edge(intersection, site, leftSection.data.site);
            Edge rightEdge = new Edge(intersection, leftSection.data.site, site);
            leftEdge.neighbour = rightEdge;

            edges.AddFirst(leftEdge);

            newSectionNode.data.edge = leftEdge;
            rightSection.data.edge   = rightEdge;

            leftSection.data.site.neighbours.Add(newSectionNode.data.site);
            newSectionNode.data.site.neighbours.Add(leftSection.data.site);

            CheckCircle(leftSection, eventQueue);
            CheckCircle(rightSection, eventQueue);
        }
        else if (leftSection != null && rightSection != null)
        {
            Point start        = new Point((leftSection.data.site.x + site.x) / 2, double.MinValue);
            Edge  infiniteEdge = new Edge(start, leftSection.data.site, site);
            Edge  newEdge      = new Edge(start, site, leftSection.data.site);

            newEdge.neighbour = infiniteEdge;
            edges.AddFirst(newEdge);

            leftSection.data.site.neighbours.Add(newSectionNode.data.site);
            newSectionNode.data.site.neighbours.Add(leftSection.data.site);

            newSectionNode.data.edge = newEdge;
        }
        else if (leftSection != null && leftSection != rightSection)
        {
            if (leftSection.data.circleEvent != null)
            {
                deleted.Add(leftSection.data.circleEvent);
                leftSection.data.circleEvent = null;
            }

            if (rightSection.data.circleEvent != null)
            {
                deleted.Add(rightSection.data.circleEvent);
                rightSection.data.circleEvent = null;
            }

            FortuneSite leftSite = leftSection.data.site;
            double      aX       = leftSite.x;
            double      aY       = leftSite.y;
            double      bX       = site.x - aX;
            double      bY       = site.y - aY;

            FortuneSite rightSite  = rightSection.data.site;
            double      cX         = rightSite.x - aX;
            double      cY         = rightSite.y - aY;
            double      delta      = bX * cY - bY * cX;
            double      magnitudeB = bX * bX + bY * bY;
            double      magnitudeC = cX * cX + cY * cY;

            Point vertex = new Point(
                (cY * magnitudeB - bY * magnitudeC) / (2 * delta) + aX,
                (bX * magnitudeC - cX * magnitudeB) / (2 * delta) + aY
                );

            rightSection.data.edge.end = vertex;

            newSectionNode.data.edge = new Edge(vertex, site, leftSection.data.site);
            rightSection.data.edge   = new Edge(vertex, rightSection.data.site, site);

            edges.AddFirst(newSectionNode.data.edge);
            edges.AddFirst(rightSection.data.edge);

            newSectionNode.data.site.neighbours.Add(leftSection.data.site);
            leftSection.data.site.neighbours.Add(newSectionNode.data.site);

            newSectionNode.data.site.neighbours.Add(rightSection.data.site);
            rightSection.data.site.neighbours.Add(newSectionNode.data.site);

            CheckCircle(leftSection, eventQueue);
            CheckCircle(rightSection, eventQueue);
        }
    }
Exemplo n.º 18
0
 public static Vector2 ToVector2(this FortuneSite site)
 {
     return(new Vector2((float)site.X, (float)site.Y));
 }
Exemplo n.º 19
0
 public void Initialize(FortuneSite site)
 {
     Site = site;
 }