private OwnVector2 findNearestOppositeEdge(CircularLinkedList<Vertex> LAV, Vertex current, out Vertex firstEdgePoint, out Vertex secondEdgePoint) { firstEdgePoint = null; secondEdgePoint = null; Node<Vertex> temp = LAV.Find(current).Next; Point2D intersectionPoint = new Point2D(0,0); Point2D currentClosest = new Point2D(0, 0); Vertices testPoly = new Vertices(); foreach(Vertex v in LAV) { testPoly.Add(v.getPoint()); } while (!temp.Next.Value.Equals(current)) { //check if the edge is not behind the vertex if(LineTools.LineIntersect( current.getRayStart(), new Point2D(current.getRayStart().X + (-current.getRayDirection().X * int.MaxValue), -current.getRayStart().Y + (-current.getRayDirection().Y * int.MaxValue)), temp.Value.getPoint(), temp.Next.Value.getPoint(), true,false, out intersectionPoint)) { //Calc Bi (intersection ray current + bisector of triangle) Point2D intersect1 = new Point2D(LineTools.LineIntersect( current.prevEdge.getFirstPoint(), current.prevEdge.getSecondPoint(), temp.Value.getPoint(), temp.Next.Value.getPoint())); Point2D intersect2 = new Point2D(LineTools.LineIntersect( current.nextEdge.getFirstPoint(), current.nextEdge.getSecondPoint(), temp.Value.getPoint(), temp.Next.Value.getPoint())); Vertices tempVer = new Vertices(); tempVer.Add(current.getPoint()); tempVer.Add(intersect1); tempVer.Add(intersect2); Vertex edgeBisector1 = new Vertex(intersect1, -1); edgeBisector1.prevEdge = new Edge(current.getPoint(), intersect1); edgeBisector1.nextEdge = new Edge(intersect1, intersect2); edgeBisector1.update(); Point2D Bi = new Point2D(LineTools.LineIntersect( current.getRayStart(), current.getRayStepPoint(), edgeBisector1.getRayStart(), edgeBisector1.getRayStepPoint())); if (tempVer.PointInPolygon(ref Bi) == -1) { edgeBisector1 = new Vertex(intersect2, -1); edgeBisector1.prevEdge = new Edge(current.getPoint(), intersect2); edgeBisector1.nextEdge = new Edge(intersect2, intersect1); edgeBisector1.update(); Bi = new Point2D(LineTools.LineIntersect( current.getRayStart(), current.getRayStepPoint(), edgeBisector1.getRayStart(), edgeBisector1.getRayStepPoint())); if (tempVer.PointInPolygon(ref Bi) == -1) { temp = temp.Next; continue; } } //check if Bi inside polygon to begin with if (testPoly.PointInPolygon(ref Bi) == -1) { temp = temp.Next; continue; } //check if Bi is in area defined by opposing edge and it's bisectors //first check if both bisectors of edge are convex so we can see if Bi is inside the defined triangle if(temp.Value.isConvex() && temp.Next.Value.isConvex()) { OwnVector2 trianglePoint = LineTools.LineIntersect( temp.Value.getRayStart(), temp.Value.getRayStepPoint(), temp.Next.Value.getRayStart(), temp.Next.Value.getRayStepPoint()); if (!MathHelper.PointInTriangle(trianglePoint, temp.Value.getPoint(), temp.Next.Value.getPoint(), Bi)) { temp = temp.Next; continue; } } else{ Vertices test = new Vertices(); int sign1 = temp.Value.isConvex() ? 1 : -1; int sign2 = temp.Next.Value.isConvex() ? 1 : -1; test.Add(temp.Value.getPoint()); test.Add(temp.Next.Value.getPoint()); test.Add(new Point2D( temp.Next.Value.getPoint().X + (sign2 * temp.Next.Value.getRayDirection().X * int.MaxValue), temp.Next.Value.getPoint().Y + (sign2 * temp.Next.Value.getRayDirection().Y * int.MaxValue))); test.Add(new Point2D( temp.Value.getPoint().X + (sign1 * temp.Value.getRayDirection().X * int.MaxValue), temp.Value.getPoint().Y + (sign1 * temp.Value.getRayDirection().Y * int.MaxValue))); if (test.PointInPolygon(ref Bi) == -1) { temp = temp.Next; continue; } } if (currentClosest.Equals(Point2D.Zero) || Point2D.Distance(current.getPoint(), currentClosest) > Point2D.Distance(current.getPoint(), Bi)) { currentClosest = Bi; firstEdgePoint = temp.Value; secondEdgePoint = temp.Next.Value; } } temp = temp.Next; } testDots.Add(currentClosest); return currentClosest; }
private void findClosestIntersectionAndStore(CircularLinkedList<Vertex> LAV, Vertex prev, Vertex current, Vertex next) { Vertices testPoly = new Vertices(); foreach (Vertex v in LAV) { testPoly.Add(v.getPoint()); } OwnVector2 prevIntersection = LineTools.LineIntersect( prev.getRayStart(), prev.getRayStepPoint(), current.getRayStart(), current.getRayStepPoint()); OwnVector2 nextIntersection = LineTools.LineIntersect( current.getRayStart(), current.getRayStepPoint(), next.getRayStart(), next.getRayStepPoint()); OwnVector2 nearestOppositeIntersection = OwnVector2.Zero; Point2D testPrev = new Point2D(prevIntersection); if (testPoly.PointInPolygon(ref testPrev) == -1) { prevIntersection = Point2D.Zero; } Point2D testNext = new Point2D(nextIntersection); if (testPoly.PointInPolygon(ref testNext) == -1) { nextIntersection = Point2D.Zero; } Vertex firstEdgePoint = null; Vertex secondEdgePoint = null; if(current.isConcave()) { nearestOppositeIntersection = findNearestOppositeEdge(LAV, current, out firstEdgePoint, out secondEdgePoint); } float distPrev = prevIntersection.Equals(Point2D.Zero) ? float.MaxValue : OwnVector2.Distance(current.getPoint(), prevIntersection); float distNext = nextIntersection.Equals(Point2D.Zero) ? float.MaxValue : OwnVector2.Distance(current.getPoint(), nextIntersection); float distOpposite = float.MaxValue; if (distPrev == 0) { prevIntersection = Point2D.Zero; } if (distNext == 0) { nextIntersection = Point2D.Zero; } if (current.isConcave()) { distOpposite = OwnVector2.Distance(current.getPoint(), nearestOppositeIntersection); } if (prevIntersection.Equals(OwnVector2.Zero) && nextIntersection.Equals(OwnVector2.Zero) && nearestOppositeIntersection.Equals(OwnVector2.Zero)) { return; } if ((nextIntersection.Equals(OwnVector2.Zero) && nearestOppositeIntersection.Equals(OwnVector2.Zero)) || distPrev < distNext && distPrev < distOpposite) { Event e = new Event(new Point2D(prevIntersection), SLAV.IndexOf(LAV), EventType.Edge); e.storeFirstPoint(prev); e.storeSecondPoint(current); Q.Enqueue(e, distPrev); } else if ((nearestOppositeIntersection.Equals(OwnVector2.Zero) && prevIntersection.Equals(OwnVector2.Zero)) || distNext <= distPrev && distNext <= distOpposite) { Event e = new Event(new Point2D(nextIntersection), SLAV.IndexOf(LAV), EventType.Edge); e.storeFirstPoint(current); e.storeSecondPoint(next); Q.Enqueue(e, distNext); } else { Event e = new Event(new Point2D(nearestOppositeIntersection), SLAV.IndexOf(LAV), EventType.Split); e.storeFirstPoint(current); e.storeFirstEdgePoint(firstEdgePoint); e.storeSecondEdgePoint(secondEdgePoint); Q.Enqueue(e, distOpposite); } }