cart: empty [ Login ]

Convert Arc to polyline

1 
CSGemini
5/24/2022 7:53 AM
I'm struggling a bit with this. I have tried adapting a few similar forum posts without success. Basically I have a number of items in the cad file, lines and arcs. I can convert a series of connected lines to a polyline without problem. The issue is when i come across a line that connects to an arc. Do we have an example of converting an arc to a polyline ?
Wout
5/24/2022 8:09 AM
Hi, The vertex Bulge property defines the curvature, the documentation should provide all the information you need, including references to methods to calculate the Bulge value. - Wout
CSGemini
5/24/2022 8:11 AM
I did find the below code in a netDxf library which worked really well in that library and was trying to adapt it for Cadlib but not finding it that easy to map the objects between libraries:
C# Code:
internal class ArcToPolyLine { /// <summary> /// Converts the arc in a Polyline2D. /// </summary> /// <param name="precision">Number of divisions.</param> /// <returns>A new instance of <see cref="Polyline2D">Polyline2D</see> that represents the arc.</returns> public Polyline2D ToPolyline2D(int precision) { IEnumerable<Vector2> vertexes = this.PolygonalVertexes(precision); Vector3 ocsCenter = MathHelper.Transform(this.center, this.Normal, CoordinateSystem.World, CoordinateSystem.Object); Polyline2D poly = new Polyline2D { Layer = (Layer)this.Layer.Clone(), Linetype = (Linetype)this.Linetype.Clone(), Color = (AciColor)this.Color.Clone(), Lineweight = this.Lineweight, Transparency = (Transparency)this.Transparency.Clone(), LinetypeScale = this.LinetypeScale, Normal = this.Normal, Elevation = ocsCenter.Z, Thickness = this.Thickness, IsClosed = false }; foreach (Vector2 v in vertexes) { poly.Vertexes.Add(new Polyline2DVertex(v.X + ocsCenter.X, v.Y + ocsCenter.Y)); } return poly; } /// <summary> /// Transforms a point between coordinate systems. /// </summary> /// <param name="point">Point to transform.</param> /// <param name="zAxis">Object normal vector.</param> /// <param name="from">Point coordinate system.</param> /// <param name="to">Coordinate system of the transformed point.</param> /// <returns>Transformed point.</returns> public static Vector3 Transform(Vector3 point, Vector3 zAxis, CoordinateSystem from, CoordinateSystem to) { Matrix3 trans = ArbitraryAxis(zAxis); switch (from) { case CoordinateSystem.World when to == CoordinateSystem.Object: trans = trans.Transpose(); return trans * point; case CoordinateSystem.Object when to == CoordinateSystem.World: return trans * point; default: return point; } } /// <summary> /// Gets the rotation matrix from the normal vector (extrusion direction) of an entity. /// </summary> /// <param name="zAxis">Normal vector.</param> /// <returns>Rotation matrix.</returns> public static Matrix3 ArbitraryAxis(Vector3 zAxis) { zAxis.Normalize(); if (zAxis.Equals(Vector3.UnitZ)) { return Matrix3.Identity; } Vector3 wY = Vector3.UnitY; Vector3 wZ = Vector3.UnitZ; Vector3 aX; if ((Math.Abs(zAxis.X) < 1 / 64.0) && (Math.Abs(zAxis.Y) < 1 / 64.0)) { aX = Vector3.CrossProduct(wY, zAxis); } else { aX = Vector3.CrossProduct(wZ, zAxis); } aX.Normalize(); Vector3 aY = Vector3.CrossProduct(zAxis, aX); aY.Normalize(); return new Matrix3(aX.X, aY.X, zAxis.X, aX.Y, aY.Y, zAxis.Y, aX.Z, aY.Z, zAxis.Z); } }
Wout
5/24/2022 8:23 AM
This code is approximating an arc with line segments. I assume you want to retain the actual arcs. My best advice is still reading the vertex Bulge property documentation and following the leads. - Wout
CSGemini
5/24/2022 8:27 AM
Thanks. I'm starting to see where you are coming from now and getting some better results.
CSGemini
5/24/2022 9:49 AM
So building on your suggestion I came up with this. Needs a little more work to take into account clockwise or counter clockwise and a few other bits but you probably get the jist of it: var a = (DxfArc)i; DxfPolyline2D polyarc = new DxfPolyline2D(); polyarc.Vertices.Add(a.GetXStart(), a.GetYStart()); polyarc.Vertices.Add(a.GetXEnd(), a.GetYEnd()); polyarc.Vertices[0].Bulge = GetArcBulge(a); pl.Vertices.AddRange(polyarc.Vertices); The only issue i see is that the polyline seems to lack a bit of precision. In the attached the white line is the polyline with the buldge and the red the original arc. The arc is smoother. Any pointers on how to improve on that.....
arctopolyline.jpg
Wout
5/24/2022 9:57 AM
Hi, You could increase GraphicsConfig.NoOfArcLineSegments, but this is at the cost of performance/memory usage. - Wout
1