Exemple #1
0
        private void GetVisiblePoints(int holeIndex, List <Polygon> polygons, out ConnectionEdge M, out ConnectionEdge P)
        {
            M = FindLargest(polygons[holeIndex]);

            var direction = (polygons[holeIndex].Start.Next.Origin - polygons[holeIndex].Start.Origin).Cross(Normal);
            var I         = FindPointI(M, polygons, holeIndex, direction);

            Vector3m res;

            if (polygons[I.PolyIndex].Contains(I.I, out res))
            {
                var incidentEdges =
                    (List <ConnectionEdge>)res.DynamicProperties.GetValue(PropertyConstants.IncidentEdges);
                foreach (var connectionEdge in incidentEdges)
                {
                    if (Misc.IsBetween(connectionEdge.Origin, connectionEdge.Next.Origin, connectionEdge.Prev.Origin, M.Origin, Normal) == 1)
                    {
                        P = connectionEdge;
                        return;
                    }
                }
                throw new Exception();
            }
            else
            {
                P = FindVisiblePoint(I, polygons, M, direction);
            }
        }
Exemple #2
0
        private ConnectionEdge FindLargest(Polygon testHole)
        {
            Rational       maximum = 0;
            ConnectionEdge maxEdge = null;
            Vector3m       v0      = testHole.Start.Origin;
            Vector3m       v1      = testHole.Start.Next.Origin;

            foreach (var connectionEdge in testHole.GetPolygonCirculator())
            {
                // we take the first two points as a reference line

                if (Misc.GetOrientation(v0, v1, connectionEdge.Origin, Normal) < 0)
                {
                    var r = Misc.PointLineDistance(v0, v1, connectionEdge.Origin);
                    if (r > maximum)
                    {
                        maximum = r;
                        maxEdge = connectionEdge;
                    }
                }
            }
            if (maxEdge == null)
            {
                return(testHole.Start);
            }
            return(maxEdge);
        }
Exemple #3
0
        private void InsertNewEdges(ConnectionEdge insertionEdge, ConnectionEdge m)
        {
            insertionEdge.Polygon.PointCount += m.Polygon.PointCount;
            var cur         = m;
            var forwardEdge = new ConnectionEdge(insertionEdge.Origin, insertionEdge.Polygon);

            forwardEdge.Prev      = insertionEdge.Prev;
            forwardEdge.Prev.Next = forwardEdge;
            forwardEdge.Next      = m;
            forwardEdge.Next.Prev = forwardEdge;
            var            end  = insertionEdge;
            ConnectionEdge prev = null;

            do
            {
                cur.Polygon = insertionEdge.Polygon;
                prev        = cur;
                cur         = cur.Next;
            } while (m != cur);
            var backEdge = new ConnectionEdge(cur.Origin, insertionEdge.Polygon);

            cur           = prev;
            cur.Next      = backEdge;
            backEdge.Prev = cur;
            backEdge.Next = end;
            end.Prev      = backEdge;
        }
Exemple #4
0
        internal void Remove(ConnectionEdge cur)
        {
            cur.Prev.Next = cur.Next;
            cur.Next.Prev = cur.Prev;
            var incidentEdges = (List <ConnectionEdge>)cur.Origin.DynamicProperties.GetValue(PropertyConstants.IncidentEdges);
            int index         = incidentEdges.FindIndex(x => x.Equals(cur));

            Debug.Assert(index >= 0);
            incidentEdges.RemoveAt(index);
            if (incidentEdges.Count == 0)
            {
                PointCount--;
            }
            if (cur == Start)
            {
                Start = cur.Prev;
            }
        }
Exemple #5
0
        private ConnectionEdge FindVisiblePoint(Candidate I, List <Polygon> polygons, ConnectionEdge M, Vector3m direction)
        {
            ConnectionEdge P = null;

            if (I.Origin.Origin.X > I.Origin.Next.Origin.X)
            {
                P = I.Origin;
            }
            else
            {
                P = I.Origin.Next;
            }

            List <ConnectionEdge> nonConvexPoints = FindNonConvexPoints(polygons[I.PolyIndex]);


            nonConvexPoints.Remove(P);

            var m = M.Origin;
            var i = I.I;
            var p = P.Origin;
            List <ConnectionEdge> candidates = new List <ConnectionEdge>();

            // invert i and p if triangle is oriented CW
            if (Misc.GetOrientation(m, i, p, Normal) == -1)
            {
                var tmp = i;
                i = p;
                p = tmp;
            }

            foreach (var nonConvexPoint in nonConvexPoints)
            {
                if (Misc.PointInOrOnTriangle(m, i, p, nonConvexPoint.Origin, Normal))
                {
                    candidates.Add(nonConvexPoint);
                }
            }
            if (candidates.Count == 0)
            {
                return(P);
            }
            return(FindMinimumAngle(candidates, m, direction));
        }
Exemple #6
0
        private ConnectionEdge FindMinimumAngle(List <ConnectionEdge> candidates, Vector3m M, Vector3m direction)
        {
            Rational       angle  = -double.MaxValue;
            ConnectionEdge result = null;

            foreach (var R in candidates)
            {
                var a     = direction;
                var b     = R.Origin - M;
                var num   = a.Dot(b) * a.Dot(b);
                var denom = b.Dot(b);
                var res   = num / denom;
                if (res > angle)
                {
                    result = R;
                    angle  = res;
                }
            }
            return(result);
        }
Exemple #7
0
        private Candidate FindPointI(ConnectionEdge M, List <Polygon> polygons, int holeIndex, Vector3m direction)
        {
            Candidate candidate = new Candidate();

            for (int i = 0; i < polygons.Count; i++)
            {
                if (i == holeIndex) // Don't test the hole with itself
                {
                    continue;
                }
                foreach (var connectionEdge in polygons[i].GetPolygonCirculator())
                {
                    Rational rayDistanceSquared;
                    Vector3m intersectionPoint;

                    if (RaySegmentIntersection(out intersectionPoint, out rayDistanceSquared, M.Origin, direction, connectionEdge.Origin,
                                               connectionEdge.Next.Origin, direction))
                    {
                        if (rayDistanceSquared == candidate.currentDistance)  // if this is an M/I edge, then both edge and his twin have the same distance; we take the edge where the point is on the left side
                        {
                            if (Misc.GetOrientation(connectionEdge.Origin, connectionEdge.Next.Origin, M.Origin, Normal) == 1)
                            {
                                candidate.currentDistance = rayDistanceSquared;
                                candidate.Origin          = connectionEdge;
                                candidate.PolyIndex       = i;
                                candidate.I = intersectionPoint;
                            }
                        }
                        else if (rayDistanceSquared < candidate.currentDistance)
                        {
                            candidate.currentDistance = rayDistanceSquared;
                            candidate.Origin          = connectionEdge;
                            candidate.PolyIndex       = i;
                            candidate.I = intersectionPoint;
                        }
                    }
                }
            }
            return(candidate);
        }
Exemple #8
0
        private void LinkAndAddToList(Polygon polygon, List <Vector3m> points)
        {
            ConnectionEdge prev = null, first = null;
            Dictionary <Vector3m, Vector3m> pointsHashSet = new Dictionary <Vector3m, Vector3m>();
            int pointCount = 0;

            for (int i = 0; i < points.Count; i++)
            {
                // we don't wanna have duplicates
                Vector3m p0;
                if (pointsHashSet.ContainsKey(points[i]))
                {
                    p0 = pointsHashSet[points[i]];
                }
                else
                {
                    p0 = points[i];
                    pointsHashSet.Add(p0, p0);
                    List <ConnectionEdge> list = new List <ConnectionEdge>();
                    p0.DynamicProperties.AddProperty(PropertyConstants.IncidentEdges, list);
                    pointCount++;
                }
                ConnectionEdge current = new ConnectionEdge(p0, polygon);

                first = (i == 0) ? current : first; // remember first

                if (prev != null)
                {
                    prev.Next = current;
                }
                current.Prev = prev;
                prev         = current;
            }
            first.Prev         = prev;
            prev.Next          = first;
            polygon.Start      = first;
            polygon.PointCount = pointCount;
        }
Exemple #9
0
        internal void AddIncidentEdge(ConnectionEdge next)
        {
            var list = (List <ConnectionEdge>)Origin.DynamicProperties.GetValue(PropertyConstants.IncidentEdges);

            list.Add(next);
        }
Exemple #10
0
 protected bool Equals(ConnectionEdge other)
 {
     return(Next.Origin.Equals(other.Next.Origin) && Origin.Equals(other.Origin));
 }
Exemple #11
0
        private bool IsConvex(ConnectionEdge curPoint)
        {
            int orientation = Misc.GetOrientation(curPoint.Prev.Origin, curPoint.Origin, curPoint.Next.Origin, Normal);

            return(orientation == 1);
        }