我正在创建一个供工业机器人使用的DXF解析器。机器人只能在直线和圆弧中移动,所以我不得不将椭圆实体分解为一系列biarc(感谢Keeper的弧函数)。转换工作完美,但是当我尝试将弧线绘制为画布上的路径时,有些是未对齐的。
我知道这些弧非常冗余,否则我的轮廓分组算法会使它们成为单独的路径,所以它肯定是一个显示问题(我还手动检查了起点和终点并确认了这一点)。我还使用相同的方法导出了一系列biarcs,但是却从SolidWorks手中导出并遇到了同样的问题。
这是表格上输出的图像,我已经圈出了biarcs未对齐的位置:
这是用于参考的椭圆转换代码,它只是对椭圆段2n
次进行采样,其中n
是所需的弧数。然后使用Keeper的3点弧函数,它为每组3点绘制弧线。
Public Function Ellipse2DToArcs(ByVal CenterPoint As XYZPoint, ByVal MajorRadius As Double, ByVal MinorRadius As Double, ByVal StartAngle As Double, ByVal EndAngle As Double, ByVal OffsetAngle As Double)
Dim PointList As New List(Of XYZPoint)
Dim ArcList As New List(Of ShapeClasses.ArcClass)
For i = StartAngle To EndAngle Step (EndAngle - StartAngle) / (My.Settings.EllipseApprox * 2)
PointList.Add(New XYZPoint With {.X = CenterPoint.X + MajorRadius * Math.Cos(i) * Math.Cos(OffsetAngle) - MinorRadius * Math.Sin(i) * Math.Sin(OffsetAngle), .Y = CenterPoint.Y + MajorRadius * Math.Cos(i) * Math.Sin(OffsetAngle) + MinorRadius * Math.Sin(i) * Math.Cos(OffsetAngle)})
Next
For i As UInteger = 1 To PointList.Count - 2 Step 2
Dim D As Double = 2 * (PointList(i - 1).X - PointList(i + 1).X) * (PointList(i + 1).Y - PointList(i).Y) + 2 * (PointList(i).X - PointList(i + 1).X) * (PointList(i - 1).Y - PointList(i + 1).Y)
Dim M1 As Double = ((PointList(i - 1).X ^ 2) - (PointList(i + 1).X ^ 2) + (PointList(i - 1).Y ^ 2) - (PointList(i + 1).Y ^ 2))
Dim M2 As Double = ((PointList(i + 1).X ^ 2) - (PointList(i).X ^ 2) + (PointList(i + 1).Y ^ 2) - (PointList(i).Y ^ 2))
Dim NX As Double = M1 * (PointList(i + 1).Y - PointList(i).Y) + M2 * (PointList(i + 1).Y - PointList(i - 1).Y)
Dim NY As Double = M1 * (PointList(i).X - PointList(i + 1).X) + M2 * (PointList(i - 1).X - PointList(i + 1).X)
Dim CX As Double = NX / D
Dim CY As Double = NY / D
ArcList.Add(New ShapeClasses.ArcClass With {.Radius = Math.Sqrt((CX - PointList(i + 1).X) ^ 2 + (CY - PointList(i + 1).Y) ^ 2), .CenterPoint = New XYZPoint With {.X = CX, .Y = CY}, .StartPoint = PointList(i - 1), .EndPoint = PointList(i + 1)})
Next
Return ArcList.ToArray
End Function
这是将Arc对象转换为图形的代码(它存储为起点,端点,中心点和半径):
Public Function Arc2DToDraw(ByVal Arc As ShapeClasses.ArcClass)
'calculate start angle
Dim StartAngle As Single = Math.Atan2(Arc.StartPoint.Y - Arc.CenterPoint.Y, Arc.StartPoint.X - Arc.CenterPoint.X) * (180 / Math.PI)
'calculate end angle
Dim EndAngle As Single = Math.Atan2(Arc.EndPoint.Y - Arc.CenterPoint.Y, Arc.EndPoint.X - Arc.CenterPoint.X) * (180 / Math.PI)
If StartAngle = EndAngle Then 'is a circle
'359.99 is a kludge to prevent a chord forming between 0 and 270 (why I have no idea)
Return {New System.Drawing.Rectangle(Arc.CenterPoint.X - Arc.Radius, Arc.CenterPoint.Y - Arc.Radius, Arc.Radius * 2, Arc.Radius * 2), StartAngle, CSng(359.99)}
Else
Return {New System.Drawing.Rectangle(Arc.CenterPoint.X - Arc.Radius, Arc.CenterPoint.Y - Arc.Radius, Arc.Radius * 2, Arc.Radius * 2), StartAngle, -(StartAngle - EndAngle)}
End If
End Function
这个问题是否有解决方案,还是固有的显示问题?
答案 0 :(得分:0)
<强>解决:强>
问题在于我使用基于整数的Rectangle
而不是基于浮点数的RectangleF
,它在绘制弧时调用了变窄的转换。
New System.Drawing.Rectangle(Arc.CenterPoint.X - Arc.Radius, Arc.CenterPoint.Y - Arc.Radius, Arc.Radius * 2, Arc.Radius * 2)
应改为:
New System.Drawing.RectangleF(Arc.CenterPoint.X - Arc.Radius, Arc.CenterPoint.Y - Arc.Radius, Arc.Radius * 2, Arc.Radius * 2)