public void SqueezeEvent(VoronoiArcNode node) { VoronoiEdgeNode leftEdge = VoronoiNode.GetLeftParentEdge(node); VoronoiEdgeNode rightEdge = VoronoiNode.GetRightParentEdge(node); VoronoiArcNode leftArc = VoronoiNode.GetLeftChildArc(leftEdge); VoronoiArcNode rightArc = VoronoiNode.GetRightChildArc(rightEdge); if (leftArc == null || rightArc == null || leftArc.mFocus == rightArc.mFocus) { return; } Vector2 intersection = GetIntersection(leftEdge, rightEdge); if (intersection.Equals(new Vector2(-10000, -10000))) { return; } float circleX = leftArc.mFocus.x - intersection.x; float circleY = leftArc.mFocus.y - intersection.y; float radius = Mathf.Sqrt((circleX * circleX) + (circleY * circleY)); if (intersection.y - radius >= sweepY) { return; } SqueezeEvent squeezeEvent = new SqueezeEvent(intersection, node); node.squeezeEvent = squeezeEvent; eventQueue.Add(squeezeEvent); }
public float GetXCoord(VoronoiNode node, float yPos) { VoronoiArcNode left = VoronoiNode.GetLeftChildArc(node); VoronoiArcNode right = VoronoiNode.GetRightChildArc(node); Vector2 leftFocus = left.mFocus; Vector2 rightFocus = right.mFocus; // Get the x coordinate intersections by using the discriminant // Work backwards from the parabola equation to get the a, b, and c values float dp = 2.0f * (leftFocus.y - yPos); float a1 = 1.0f / dp; float b1 = -2.0f * leftFocus.x / dp; float c1 = yPos + dp / 4.0f + leftFocus.x * leftFocus.x / dp; dp = 2.0f * (rightFocus.y - yPos); float a2 = 1.0f / dp; float b2 = -2.0f * rightFocus.x / dp; float c2 = yPos + dp / 4.0f + rightFocus.x * rightFocus.x / dp; float a = a1 - a2; float b = b1 - b2; float c = c1 - c2; float discriminant = b * b - 4 * a * c; float x1 = (-b + Mathf.Sqrt(discriminant)) / (2 * a); float x2 = (-b - Mathf.Sqrt(discriminant)) / (2 * a); float xCoord; if (leftFocus.y < rightFocus.y) { xCoord = Mathf.Max(x1, x2); } else { xCoord = Mathf.Min(x1, x2); } return(xCoord); }
public void RemoveArc(SqueezeEvent vEvent) { VoronoiArcNode removeNode = vEvent.mArcToRemove; VoronoiEdgeNode leftEdge = VoronoiNode.GetLeftParentEdge(removeNode); VoronoiEdgeNode rightEdge = VoronoiNode.GetRightParentEdge(removeNode); VoronoiArcNode leftArc = VoronoiNode.GetLeftChildArc(leftEdge); VoronoiArcNode rightArc = VoronoiNode.GetRightChildArc(rightEdge); if (leftArc.squeezeEvent != null) { removed.Add(leftArc.squeezeEvent); leftArc.squeezeEvent = null; } if (rightArc.squeezeEvent != null) { removed.Add(rightArc.squeezeEvent); rightArc.squeezeEvent = null; } Vector2 point = new Vector2(vEvent.mIntersectionPoint.x, GetYCoord(removeNode.mFocus, vEvent.mIntersectionPoint.x)); leftEdge.mEndVertex = point; rightEdge.mEndVertex = point; VoronoiNode h; VoronoiNode tempNode = removeNode; while (tempNode != root) { tempNode = tempNode.mParent; if (tempNode == leftEdge) { h = leftEdge; } if (tempNode == rightEdge) { h = rightEdge; } } h = new VoronoiEdgeNode(point, new Vector2(), leftArc.mFocus, rightArc.mFocus); //******* //edges.Add((VoronoiEdgeNode)h); VoronoiNode removeNodeGrandparent = removeNode.mParent.mParent; if (removeNode.mParent.mLeft == removeNode) { if (removeNodeGrandparent.mLeft == removeNode.mParent) { removeNodeGrandparent.mLeft = removeNode.mParent.mRight; removeNode.mParent.mRight.mParent = removeNodeGrandparent; } if (removeNodeGrandparent.mRight == removeNode.mParent) { removeNodeGrandparent.mRight = removeNode.mParent.mRight; removeNode.mParent.mRight.mParent = removeNodeGrandparent; } } else { if (removeNodeGrandparent.mLeft == removeNode.mParent) { removeNodeGrandparent.mLeft = removeNode.mParent.mLeft; removeNode.mParent.mLeft.mParent = removeNodeGrandparent; } if (removeNodeGrandparent.mRight == removeNode.mParent) { removeNodeGrandparent.mRight = removeNode.mParent.mLeft; removeNode.mParent.mLeft.mParent = removeNodeGrandparent; } } SqueezeEvent(leftArc); SqueezeEvent(rightArc); }