private List <Edge> IntersectedEdges(Vector2 edgeStart, SliceHierarchy father, Vector2 edgeEnd) { var interEdges = new List <Edge>(); for (var p = father.Points.First; p != null; p = p.Next) { if (p.Value.v2.Equals(edgeStart)) { continue; } var areIntersect = WholeSlicePlane.LineSegmentsIntersection( edgeStart, edgeEnd, p.Value.v2, LinkedListExtensions.Next(p).Value.v2, out var interPoint); //intersection point with father(outer) points if (areIntersect) { var point = p.Value.v2.x > LinkedListExtensions.Next(p).Value.v2.x ? p : LinkedListExtensions.Next(p); var edge = new Edge { FDiscret = p, SDiscret = LinkedListExtensions.Next(p), MaxXdiscret = point, Inter = interPoint }; interEdges.Add(edge); } } return(interEdges); }
private void UnionFatherAndChildPoints(SliceHierarchy child, SliceHierarchy father, LinkedListNode <MappedPoint> childStartPoint, LinkedListNode <MappedPoint> fatherStartPoint) { var prev = fatherStartPoint; for (var p3 = childStartPoint; p3 != LinkedListExtensions.Previous(childStartPoint); p3 = LinkedListExtensions.Next(p3)) { prev = father.Points.AddAfter(prev, p3.Value); } prev = father.Points .AddAfter(prev, LinkedListExtensions.Previous(childStartPoint).Value); prev = father.Points.AddAfter(prev, childStartPoint.Value); father.Points.AddAfter(prev, fatherStartPoint.Value); father.MaxX = Mathf.Max(father.MaxX, child.MaxX); }
private void ReverseIfShould(SliceHierarchy sliceHierarchy) { if (sliceHierarchy.Level % 2 == 0) { if (!ArePointsCounterClockwise(sliceHierarchy.Points)) { sliceHierarchy.Points = LinkedListExtensions.ReversedLinkedList(sliceHierarchy.Points); } } else { if (ArePointsCounterClockwise(sliceHierarchy.Points)) { sliceHierarchy.Points = LinkedListExtensions.ReversedLinkedList(sliceHierarchy.Points); } } }
private bool ArePolygonsIntersect(SliceHierarchy pol1, SliceHierarchy pol2) { for (var p1 = pol1.Points.First; p1 != null; p1 = p1.Next) { for (var p2 = pol2.Points.First; p2 != null; p2 = p2.Next) { var areIntersect = LineSegmentsIntersection(p1.Value.v2, LinkedListExtensions.Next(p1).Value.v2, p2.Value.v2, LinkedListExtensions.Next(p2).Value.v2, out var interPoint); if (areIntersect) { return(true); } } } return(false); }
private int IntersectionCount(SliceHierarchy outerPoints, MappedPoint point) { var intersectionCount = 0; for (var p = outerPoints.Points.First; p != null; p = p.Next) { var end = new Vector2(1000000f, 0); var areIntersect = LineSegmentsIntersection(point.v2, end, p.Value.v2, LinkedListExtensions.Next(p).Value.v2, out var intersection); if (areIntersect) { intersectionCount++; } } return(intersectionCount); }
private bool IsPolygonInsidePolygon(SliceHierarchy intendedСhild, SliceHierarchy intendedFather) { var intersectionCountPrev = IntersectionCount(intendedFather, intendedСhild.Points.First.Value); return(intersectionCountPrev % 2 == 1); }
public Triangulator(SliceHierarchy sliceHierarchy) { //even should be counterclockwise ReverseIfShould(sliceHierarchy); sliceHierarchy.Childs.RemoveAll(item => item == null); sliceHierarchy.Childs = new List <SliceHierarchy>(sliceHierarchy.Childs.OrderByDescending(x => x.MaxX)); for (var j = 0; j < sliceHierarchy.Childs.Count; j++) { var child = sliceHierarchy.Childs[j]; if (child == null) { continue; } //odd should be clockwise ReverseIfShould(child); // child point with max x var childMaxX = child.MaxX; LinkedListNode <MappedPoint> childMaxXObj = null; for (var p = child.Points.First; p != null; p = p.Next) { if (p.Value.v2.x == childMaxX) { childMaxXObj = p; } } //intersected edges var interEdges = IntersectedEdges(childMaxXObj.Value.v2, child.Father, new Vector2(1000000f, 0)); if (!interEdges.Any()) { continue; } // nearest edge var nearestEdgeDist = interEdges.Min(x => Mathf.Abs(x.MaxXdiscret.Value.v2.x - childMaxXObj.Value.v2.x)); Edge nearestEdge = null; foreach (var e in interEdges) { if (Mathf.Abs(e.MaxXdiscret.Value.v2.x - childMaxXObj.Value.v2.x) == nearestEdgeDist) { nearestEdge = e; break; } } // childMaxX..............................nearestEdge.Inter // .................MinAnglePoint......... // .................................P2.... // .......................................nearestEdge.discret var pointsInTriangle = PointsInTriangle( child.Father.Points, childMaxXObj.Value.v2, nearestEdge.MaxXdiscret.Value.v2, nearestEdge.Inter); // if points were caught than should pick with smallest angle if (pointsInTriangle.Any()) { var minAngleObj = pointsInTriangle .OrderBy(x => Vector2.Angle(nearestEdge.Inter - childMaxXObj.Value.v2, x.Value.v2 - childMaxXObj.Value.v2)) .ThenBy(x => Mathf.Abs(x.Value.v2.x - childMaxXObj.Value.v2.x)).First(); nearestEdge.MaxXdiscret = minAngleObj; } //intersected edges var selfInterEdges = IntersectedEdges(childMaxXObj.Value.v2, child, nearestEdge.MaxXdiscret.Value.v2); if (selfInterEdges.Any()) { childMaxXObj = selfInterEdges .OrderBy(x => Vector2.Distance(x.MaxXdiscret.Value.v2, nearestEdge.MaxXdiscret.Value.v2)) .First() .MaxXdiscret; } // union father and child UnionFatherAndChildPoints( child, child.Father, childMaxXObj, nearestEdge.MaxXdiscret); sliceHierarchy.Childs[j] = null; } _pointsN = sliceHierarchy.Points; }