//Added by Dozed internal VEdge(VPoint start, VPoint end, FortuneSite left, FortuneSite right) { Start = start; End = end; Left = left; Right = right; }
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; }
public Vector2Edge(Vector2X Start, Vector2X End, FortuneSite Left, FortuneSite Right) { start = Start; end = End; left = Left; right = Right; }
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); }
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; }
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); }
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); }
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); }
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; }
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); }
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)); }
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)); }
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); }
public FortuneSiteEvent(FortuneSite site) { this.site = site; }
internal FortuneSiteEvent(FortuneSite site) { Site = site; }
public BeachSection(FortuneSite site) { this.site = site; this.circleEvent = null; }
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); } }
public static Vector2 ToVector2(this FortuneSite site) { return(new Vector2((float)site.X, (float)site.Y)); }
public void Initialize(FortuneSite site) { Site = site; }