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); }
/// <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); }
/// <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); }
/// <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); }