Пример #1
0
        public List <CurveArray> DividePolygonInHalf(XYZ divisionDirection, out Line cutLine)
        {
            Normalize();

            CircularLinkedList <UV>             points    = GetPoints();
            List <CircularLinkedListNode <UV> > newPoints = new List <CircularLinkedListNode <UV> >();

            UV centroid = CalculatePolygonCentroid(points);

            cutLine = Line.CreateUnbound(VectorManipulator.TransformUVinXYZ(centroid), divisionDirection);

            foreach (Curve curve in curveArray)
            {
                SetComparisonResult result = cutLine.Intersect(curve, out IntersectionResultArray resultArray);
                if (result == SetComparisonResult.Overlap)
                {
                    UV  newPoint = VectorManipulator.ProjectInPlaneXY(resultArray.get_Item(0).XYZPoint);
                    XYZ p0       = curve.GetEndPoint(0);
                    XYZ p1       = curve.GetEndPoint(1);
                    newPoints.Add(AddPointBetween(points, VectorManipulator.ProjectInPlaneXY(p0), VectorManipulator.ProjectInPlaneXY(p1), newPoint));
                }
            }

            CircularLinkedList <UV> newPolygon0 = CreatePolygonBetweenVertices(newPoints[0], newPoints[1]);
            CircularLinkedList <UV> newPolygon1 = CreatePolygonBetweenVertices(newPoints[1], newPoints[0]);

            List <CurveArray> dividedCurveArrays = new List <CurveArray>
            {
                CreateCurveArrayFromPoints(newPolygon0),
                CreateCurveArrayFromPoints(newPolygon1)
            };

            cutLine = Line.CreateBound(VectorManipulator.TransformUVinXYZ(newPoints[0].Value), VectorManipulator.TransformUVinXYZ(newPoints[1].Value));
            return(dividedCurveArrays);
        }
Пример #2
0
        /// <summary>
        /// Add a new vertice in order in the list of vertices of the polygon given the IntersectionResultArray.
        /// </summary>
        /// <param name="points"></param>
        /// <param name="resultArray"></param>
        /// <param name="curve"></param>
        private static CircularLinkedListNode <UV> AddPointsInList(CircularLinkedList <UV> points, IntersectionResultArray resultArray, Curve curve)
        {
            UV p0 = VectorManipulator.ProjectInPlaneXY(curve.GetEndPoint(0));
            CircularLinkedListNode <UV> newNode = null;
            CircularLinkedListNode <UV> node    = FindPoint(points, p0);

            IntersectionResultArrayIterator iterator = resultArray.ForwardIterator();

            iterator.Reset();
            while (iterator.MoveNext())
            {
                IntersectionResult result = iterator.Current as IntersectionResult;
                UV intersectionPoint      = VectorManipulator.ProjectInPlaneXY(result.XYZPoint);
                newNode = points.AddAfter(node, intersectionPoint);
            }
            if (newNode.Next.Value.IsAlmostEqualTo(newNode.Value))
            {
                points.Remove(newNode.Next.Value);
            }
            else if (newNode.Previous.Value.IsAlmostEqualTo(newNode.Value))
            {
                points.Remove(newNode.Previous.Value);
            }

            return(newNode);
        }
Пример #3
0
        /// <summary>
        /// Get the vertices of the CurveArray
        /// </summary>
        /// <param name="curveArray">
        /// The CurveArray must be closed.
        /// </param>
        /// <returns>
        /// Returns a Linked List of UV points ordered in clock wise order.
        /// </returns>
        private CircularLinkedList <UV> GetPoints()
        {
            CircularLinkedList <UV> points = new CircularLinkedList <UV>();

            foreach (Curve curve in curveArray)
            {
                UV point2D = VectorManipulator.ProjectInPlaneXY(curve.GetEndPoint(0));
                points.AddLast(point2D);
            }
            return(points);
        }
Пример #4
0
        /// <summary>
        /// Finds a point that
        /// </summary>
        /// <param name="points"></param>
        /// <param name="line1"></param>
        /// <param name="posibleCurves"></param>
        /// <returns></returns>
        private static CircularLinkedListNode <UV> FindNewNode(ref CircularLinkedList <UV> points, Line line, CurveArray posibleCurves, UV notch)
        {
            // iterate for each possible curve, and if
            // a intersection is found, the point will
            // be added in the linked list
            CircularLinkedListNode <UV> newNode = null;

            // get the closest point
            UV     newPoint = null, previousPoint = null;
            double minDistance = double.MaxValue;

            foreach (Curve curve in posibleCurves)
            {
                SetComparisonResult intersection = curve.Intersect(line, out IntersectionResultArray resultArray);
                if (intersection == SetComparisonResult.Overlap)
                {
                    IntersectionResultArrayIterator iterator = resultArray.ForwardIterator();
                    iterator.Reset();
                    while (iterator.MoveNext())
                    {
                        IntersectionResult result = iterator.Current as IntersectionResult;
                        UV     point    = VectorManipulator.ProjectInPlaneXY(result.XYZPoint);
                        double distance = point.DistanceTo(notch);
                        if (distance < minDistance)
                        {
                            minDistance   = distance;
                            newPoint      = point;
                            previousPoint = VectorManipulator.ProjectInPlaneXY(curve.GetEndPoint(0));
                        }
                    }
                }
            }

            // insert the new point in the list
            CircularLinkedListNode <UV> node = FindPoint(points, previousPoint);

            newNode = points.AddAfter(node, newPoint);
            if (newNode.Next.Value.IsAlmostEqualTo(newNode.Value))
            {
                points.Remove(newNode.Next.Value);
            }
            else if (newNode.Previous.Value.IsAlmostEqualTo(newNode.Value))
            {
                points.Remove(newNode.Previous.Value);
            }

            return(newNode);
        }
Пример #5
0
        private bool PosibleCurve(Curve curve, CircularLinkedListNode <UV> pointNode)
        {
            // the curve cannot contain the 2 points after or before or the pointNode itself
            List <UV> forbiddenPoints = new List <UV>
            {
                pointNode.Value,
                pointNode.Previous.Value,
                pointNode.Previous.Previous.Value,
                pointNode.Next.Value,
                pointNode.Next.Next.Value
            };
            UV p0 = VectorManipulator.ProjectInPlaneXY(curve.GetEndPoint(0));
            UV p1 = VectorManipulator.ProjectInPlaneXY(curve.GetEndPoint(1));


            return(!(SearchForUVInList(forbiddenPoints, p0) && SearchForUVInList(forbiddenPoints, p1)));
        }
Пример #6
0
        /// <summary>
        /// Offset a polygon in all directions, except the edge of this polygon that is equal to the unchangedLine parameter.
        /// </summary>
        /// <param name="vertices">A list of 2D coordinates that represents the vertices of the polygon. The list must be ordered counter-clockwise</param>
        /// <param name="offset">The offset value.</param>
        /// <param name="unchangedLine">If an edge of the polygon is collinear to this line, that edge will remain unchanged.</param>
        /// <returns>Returns a List of 2D coordinates that represents the offseted polygon.</returns>
        private static CircularLinkedList <UV> OffsetPolygon(CircularLinkedList <UV> vertices, double offset, List <Line> unchangedLines)
        {
            if (offset == 0)
            {
                return(vertices);
            }

            CircularLinkedList <UV>     adjusted_points = new CircularLinkedList <UV>();
            CircularLinkedListNode <UV> node            = vertices.Head;

            do
            {
                //find the points before and after our target point.
                UV vertexI = node.Previous.Value;
                UV vertexJ = node.Value;
                UV vertexK = node.Next.Value;

                //the next step is to push out each point based on the position of its surrounding points and then
                //figure out the intersections of the pushed out points
                UV v1 = vertexJ - vertexI;
                UV v2 = vertexK - vertexJ;

                // verifies if one of the segments ij, ji, jk or kj is the unchangedLine
                if (unchangedLines != null)
                {
                    foreach (Line l in unchangedLines)
                    {
                        UV p0 = VectorManipulator.ProjectInPlaneXY(l.GetEndPoint(0));
                        UV p1 = VectorManipulator.ProjectInPlaneXY(l.GetEndPoint(1));

                        if ((vertexI.IsAlmostEqualTo(p0) && vertexJ.IsAlmostEqualTo(p1)) ||
                            (vertexJ.IsAlmostEqualTo(p0) && vertexI.IsAlmostEqualTo(p1)))
                        {
                            v1 = UV.Zero;
                            break;
                        }
                        if ((vertexJ.IsAlmostEqualTo(p0) && vertexK.IsAlmostEqualTo(p1)) ||
                            (vertexK.IsAlmostEqualTo(p0) && vertexJ.IsAlmostEqualTo(p1)))
                        {
                            v2 = UV.Zero;
                            break;
                        }
                    }
                }

                v1 = v1.Normalize() * offset;
                v2 = v2.Normalize() * offset;

                // creates a shifted line that is parallel to the vector v1
                UV   n1    = new UV(-v1.V, v1.U);
                UV   pij1  = vertexI + n1;
                UV   pij2  = vertexJ + n1;
                Line line1 = Line.CreateBound(VectorManipulator.TransformUVinXYZ(pij1), VectorManipulator.TransformUVinXYZ(pij2));
                line1.MakeUnbound();

                // creates a shifted line that is parallel to the vector v2
                UV   n2    = new UV(-v2.V, v2.U);
                UV   pjk1  = vertexJ + n2;
                UV   pjk2  = vertexK + n2;
                Line line2 = Line.CreateBound(VectorManipulator.TransformUVinXYZ(pjk1), VectorManipulator.TransformUVinXYZ(pjk2));
                line2.MakeUnbound();

                //see where the shifted lines 1 and 2 intersect
                SetComparisonResult comparisonResult = line1.Intersect(line2, out IntersectionResultArray intersection);

                if (comparisonResult == SetComparisonResult.Overlap)
                {
                    IntersectionResult result = intersection.get_Item(0);
                    UV intersection_point     = VectorManipulator.ProjectInPlaneXY(result.XYZPoint);

                    //add the intersection as our adjusted vert point
                    adjusted_points.AddLast(new UV(intersection_point.U, intersection_point.V));
                }

                node = node.Next;
            } while (node != vertices.Head);
            return(adjusted_points);
        }