Пример #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>
        /// Eliminates a notch by creating a new line between the notch and an edge of the polygon.
        /// </summary>
        /// <param name="notch">Coordinates of the notch.</param>
        /// <param name="curveArray">The polygon.</param>
        /// <param name="points">The vertices of the polygon.</param>
        /// <param name="preferredOrientation">The method will try to make a cut that is parallel to this vector.</param>
        /// <param name="cutLine">The line that cut the polygon.</param>
        /// <returns>
        /// Returns the list of the CurveArrays.
        /// </returns>
        private List <CurveArray> EliminateNotch(UV notch, CurveArray curveArray, CircularLinkedList <UV> points, XYZ preferredOrientation, out Line cutLine)
        {
            XYZ  notche3D = VectorManipulator.TransformUVinXYZ(notch);
            Line line1    = Line.CreateUnbound(notche3D, preferredOrientation);

            XYZ  otherOrientation = new XYZ(preferredOrientation.Y, preferredOrientation.X, 0);
            Line line2            = Line.CreateUnbound(notche3D, otherOrientation);

            CircularLinkedListNode <UV> notchNode = FindPoint(points, notch);

            // get the posible curves for the new point
            CurveArray posibleCurves = new CurveArray();

            foreach (Curve curve in curveArray)
            {
                if (PosibleCurve(curve, notchNode))
                {
                    posibleCurves.Append(curve);
                }
            }

            // iterate for each possible curve, and if
            // a intersection is found, the point will
            // added in the linked list
            CircularLinkedListNode <UV> newNode;

            newNode = FindNewNode(ref points, line1, posibleCurves, notch);

            if (newNode == null)
            {
                newNode = FindNewNode(ref points, line2, posibleCurves, notch);
            }

            // generates the 2 new polygons
            CircularLinkedList <UV> polygonA = CreatePolygonBetweenVertices(newNode, notchNode);
            CircularLinkedList <UV> polygonB = CreatePolygonBetweenVertices(notchNode, newNode);

            // creates the curves
            List <CurveArray> list = new List <CurveArray>
            {
                CreateCurveArrayFromPoints(polygonA),
                CreateCurveArrayFromPoints(polygonB)
            };

            // returns the cutLine
            cutLine = Line.CreateBound(notche3D, VectorManipulator.TransformUVinXYZ(newNode.Value));

            return(list);
        }
Пример #3
0
        /// <summary>
        /// Create a CurveArray given its vertices.
        /// </summary>
        public CurveArray CreateCurveArrayFromPoints(CircularLinkedList <UV> points)
        {
            CurveArray curveArray            = new CurveArray();
            CircularLinkedListNode <UV> node = points.Head;
            Line line;

            do
            {
                // for the cases that the 2 lines are colinear
                if (!node.Value.IsAlmostEqualTo(node.Next.Value))
                {
                    line = Line.CreateBound(VectorManipulator.TransformUVinXYZ(node.Value), VectorManipulator.TransformUVinXYZ(node.Next.Value));
                    curveArray.Append(line);
                }
                node = node.Next;
            } while (node != points.Head);
            return(curveArray);
        }
Пример #4
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);
        }