private void ExportNFFSmoothedPolyLineEntityToDXF(NFFLineworkSmoothedPolyLineEntity Data) { // Iterate over each pair of points var StartPt = Data.Vertices.First(); var vertices = new AddVertexCallback(); for (var I = 0; I < Data.Vertices.Count; I++) { var EndPt = Data.Vertices[I]; vertices.VertexCount = 0; NFFUtils.DecomposeSmoothPolyLineSegmentToPolyLine(StartPt, EndPt, 1.0 /* Min length*/, 100 /*Max segment length */, 1000 /*Max number of segments*/, vertices.AddVertex); if (vertices.VertexCount > 2) { var DXFPolyline = new DXFPolyLineEntity("B", kAlignmentCenterLineColor, kAlignmentCenterLineThickness) { Closed = false }; DXF.Entities.Add(DXFPolyline); for (var PtIdx = 0; PtIdx < vertices.VertexCount - 1; PtIdx++) { DXFPolyline.Entities.Add(new DXFLineEntity("B", kAlignmentCenterLineColor, vertices.Vertices[PtIdx].X, vertices.Vertices[PtIdx].Y, Consts.NullDouble, vertices.Vertices[PtIdx + 1].X, vertices.Vertices[PtIdx + 1].Y, Consts.NullDouble, kAlignmentCenterLineThickness)); } } else // Render a straight line for the curve { DXF.Entities.Add(new DXFLineEntity("B", kAlignmentCenterLineColor, StartPt.X, StartPt.Y, Consts.NullDouble, EndPt.X, EndPt.Y, Consts.NullDouble, kAlignmentCenterLineThickness)); } // Swap StartPt = EndPt; } }
public static void VectoriseSmoothPolylineTolerance(NFFLineworkSmoothedPolyLineEntity SmoothPolyline, double ATolerance, Action <double, double, DecompositionVertexLocation> DecompCallback) { // ATolerance is defined as a maximum deviation from the point being inserted to a line // between the two points at each end of the interval being inserted into. double Alpha, Beta; double AlphaPlusBeta; double TwoAlphaPlusBeta; double lx, ly; NFFLineworkSmoothedPolyLineVertexEntity StartPt, EndPt; XYZ StartPos, EndPos; XYZ GetPosition(double Ordinate) { double o2 = Ordinate * Ordinate; double Cubic = AlphaPlusBeta * o2 * Ordinate - TwoAlphaPlusBeta * o2 + Alpha * Ordinate; var Result = new XYZ(StartPt.X + lx * Ordinate, StartPt.Y + ly * Ordinate, Consts.NullDouble); if (Cubic != 0.0) { Result.X -= ly * Cubic; Result.Y += lx * Cubic; } return(Result); } void InsertIntoInterval(double IntStart, double IntEnd, XYZ startPos, XYZ endPos) { double HalfInterval = (IntStart + IntEnd) / 2; var pos = GetPosition(HalfInterval); if (Math.Abs(XYZ.GetPointOffset(startPos, endPos, pos)) > ATolerance) { // Process the interval before the point to insert InsertIntoInterval(IntStart, HalfInterval, startPos, pos); // Insert the point that divides this interval DecompCallback(pos.X, pos.Y, DecompositionVertexLocation.Intermediate); // Process the interval after before the point to insert InsertIntoInterval(HalfInterval, IntEnd, pos, endPos); } } // if SmoothPolyline.Vertices.Count < 2 then // Exit; StartPt = SmoothPolyline.Vertices.First(); EndPt = SmoothPolyline.Vertices.Last(); // lx = EndPt.X - StartPt.X; // ly = EndPt.Y - StartPt.Y; // Add the start point of the smooth polyline DecompCallback(StartPt.X, StartPt.Y, DecompositionVertexLocation.First); for (int I = 0; I < SmoothPolyline.Vertices.Count - 1; I++) { EndPt = SmoothPolyline.Vertices[I + 1]; lx = EndPt.X - StartPt.X; ly = EndPt.Y - StartPt.Y; // Cache these, for speed. Alpha = EndPt.Alpha; Beta = EndPt.Beta; // zero co-efficients means a straight line if (Alpha != 0 && Beta != 0) { AlphaPlusBeta = Alpha + Beta; TwoAlphaPlusBeta = AlphaPlusBeta + Alpha; StartPos = new XYZ(StartPt.X, StartPt.Y, StartPt.Z); EndPos = new XYZ(EndPt.X, EndPt.Y, EndPt.Z); InsertIntoInterval(0, 1, StartPos, EndPos); } if (I < SmoothPolyline.Vertices.Count - 1) { DecompCallback(EndPt.X, EndPt.Y, DecompositionVertexLocation.Intermediate); } StartPt = EndPt; } // Add the end point of the segment to the polyline vertices DecompCallback(EndPt.X, EndPt.Y, DecompositionVertexLocation.Last); }