1

我正在创建一个供工业机器人使用的 DXF 解析器。机器人只能沿直线和弧线移动,所以我不得不将椭圆实体分解成一系列的 biarc(感谢Keeper提供的弧功能)。转换效果很好,但是当我尝试在画布上绘制弧线作为路径时,有些未对齐。

我知道这些弧确实是余切的,否则我的轮廓分组算法会使它们成为单独的路径,所以这绝对是一个显示问题(我还手动检查了起点和终点并确认了这一点)。我还使用相同的方法从 SolidWorks 手动导出了一系列 biarcs,并且遇到了同样的问题。

这是表单上的输出图像,我在 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 Object 转换为图形的代码(它存储为起点、终点、中心点和半径):

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

有没有解决这个问题的方法,或者它是一个固有的显示问题?

4

1 回答 1

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) 
于 2013-04-03T10:08:52.247 回答