Hello,
Hope everyone's doing well today 🙂 I'm creating a script (ARC2PLINE) that's supposed to trace a polyline perfectly at the lines, but when it finds an arc within the polyline, it iterates a straight line segment every 100 units along the arc until the end, and then continues on its merry way to more adventures with more lines and arcs along the polyline.
So I got this script working for just plain arcs (the ARCAA command below demonstrates this), but i'm having some difficulties making it work for arcs within polylines I've gotten all manners of strange iterations (I present two below) when it should be basically tracing, it's not connecting to the line segments that surround the arc properly, I'm just really at a loss for what's going on here. Here's what I got:
<CommandMethod("ARC2PLINE")>
Public Sub ArcToPolyline_Main()
Dim ed = Application.DocumentManager.MdiActiveDocument.Editor
' Prompt the user to select a polyline
Dim plineOptions = New PromptEntityOptions(vbLf & "Select a polyline: ")
plineOptions.SetRejectMessage(vbLf & "Selected entity must be a Polyline.")
plineOptions.AddAllowedClass(GetType(Polyline), True)
Dim plineResult = ed.GetEntity(plineOptions)
If plineResult.Status <> PromptStatus.OK Then Return
Dim db = Application.DocumentManager.MdiActiveDocument.Database
Using tr = db.TransactionManager.StartTransaction()
' Get the selected polyline
Dim selectedPline = CType(tr.GetObject(plineResult.ObjectId, OpenMode.ForRead), Polyline)
' Create a new polyline for the output
Dim newPline As New Polyline()
' Iterate through the polyline segments
For index As Integer = 0 To selectedPline.NumberOfVertices - 2
Dim startPoint As Point2d = selectedPline.GetPoint2dAt(index)
Dim endPoint As Point2d = selectedPline.GetPoint2dAt(index + 1)
If selectedPline.GetSegmentType(index) = SegmentType.Arc Then
Dim arcSegment As CircularArc2d = selectedPline.GetArcSegment2dAt(index)
Dim arc As New Arc(New Point3d(arcSegment.Center.X, arcSegment.Center.Y, 0), arcSegment.Radius, arcSegment.StartAngle, arcSegment.EndAngle)
' Orient the arc correctly
If selectedPline.GetBulgeAt(index) > 0 Then
Dim temp = arc.StartAngle
arc.StartAngle = arc.EndAngle
arc.EndAngle = temp
End If
Dim arcPoints As List(Of Point2d) = GenerateArcPoints(arc)
For i As Integer = 0 To arcPoints.Count - 1
newPline.AddVertexAt(newPline.NumberOfVertices, arcPoints(i), 0, 0, 0)
Next
Else
' Add line segment points to the new polyline
If newPline.NumberOfVertices = 0 OrElse newPline.GetPoint2dAt(newPline.NumberOfVertices - 1) <> startPoint Then
newPline.AddVertexAt(newPline.NumberOfVertices, startPoint, 0, 0, 0)
End If
newPline.AddVertexAt(newPline.NumberOfVertices, endPoint, 0, 0, 0)
End If
Next
' Add the new polyline to the current space
Dim curSpace = CType(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
curSpace.AppendEntity(newPline)
tr.AddNewlyCreatedDBObject(newPline, True)
tr.Commit()
End Using
End Sub
Public Function GenerateArcPoints(arc As Arc) As List(Of Point2d)
Dim points As New List(Of Point2d)
Dim startPoint As Point2d = New Point2d(arc.StartPoint.X, arc.StartPoint.Y)
Dim endPoint As Point2d = New Point2d(arc.EndPoint.X, arc.EndPoint.Y)
points.Add(startPoint)
Dim interval As Double = 100.0
Dim arcLength As Double = arc.Length
Dim numIntervals As Integer = CInt(Math.Floor(arcLength / interval))
' Ensure that the end angle is greater than the start angle
Dim endAngle As Double = arc.EndAngle
If endAngle < arc.StartAngle Then
endAngle += 2 * Math.PI
End If
' Add a small tolerance to account for floating-point arithmetic
Dim tolerance As Double = 0.0000000001
If Math.Abs(endAngle - 2 * Math.PI) < tolerance Then
endAngle -= tolerance
End If
For i As Integer = 1 To numIntervals + 1
Dim angle = arc.StartAngle + (i * (endAngle - arc.StartAngle) / numIntervals)
' Ensure the angle stays within bounds
If angle > endAngle Then
angle = endAngle
ElseIf angle < arc.StartAngle Then
angle = arc.StartAngle
End If
' Convert angle to point on the arc using center, radius, and angle
Dim pointOnArc = New Point3d(arc.Center.X + arc.Radius * Math.Cos(angle), arc.Center.Y + arc.Radius * Math.Sin(angle), arc.Center.Z)
Dim pointOnArc2d = New Point2d(pointOnArc.X, pointOnArc.Y)
points.Add(pointOnArc2d)
If angle = endAngle Then
Exit For
End If
Next
Return points
End Function
<CommandMethod("ARCAA")>
Public Sub TestGenerateArcPoints()
Dim doc = Application.DocumentManager.MdiActiveDocument
Dim db = doc.Database
Dim ed = doc.Editor
' Prompt the user to select an arc
Dim arcOptions = New PromptEntityOptions(vbLf & "Select an arc: ")
arcOptions.SetRejectMessage(vbLf & "Selected entity must be an Arc.")
arcOptions.AddAllowedClass(GetType(Arc), True)
Dim arcResult = ed.GetEntity(arcOptions)
If arcResult.Status <> PromptStatus.OK Then Return
Using tr = db.TransactionManager.StartTransaction()
' Get the selected arc
Dim selectedArc = CType(tr.GetObject(arcResult.ObjectId, OpenMode.ForRead), Arc)
' Generate the points on the arc
Dim points = GenerateArcPoints(selectedArc)
' Draw the points on the arc
Dim curSpace = CType(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
For Each point In points
Dim point3d = New Point3d(point.X, point.Y, 0)
Dim dbPoint = New DBPoint(point3d)
curSpace.AppendEntity(dbPoint)
tr.AddNewlyCreatedDBObject(dbPoint, True)
Next
tr.Commit()
End Using
End Sub
And here is the before and after, notice the exotic shape it makes if I attempt to use it on a very simple filleted polyline:
And here is what it would look like an earlier version i still have access to:
Solved! Go to Solution.