Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
 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);
         }
     }
 }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        private bool IsPolygonInsidePolygon(SliceHierarchy intendedСhild, SliceHierarchy intendedFather)
        {
            var intersectionCountPrev = IntersectionCount(intendedFather, intendedСhild.Points.First.Value);

            return(intersectionCountPrev % 2 == 1);
        }
Пример #7
0
        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;
        }