首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >双弧绘制

问双弧绘制
EN

Stack Overflow用户
提问于 2013-03-28 20:28:52
回答 1查看 293关注 0票数 1

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

我知道这些圆弧实际上是相切的,否则我的轮廓分组算法会让它们分开路径,所以这肯定是一个显示问题(我也手动检查了起点和终点,并确认了这一点)。我还使用相同的方法导出了一系列的biarcs,但都是手工从SolidWorks导出的,并且遇到了同样的问题。

这是表单上输出的图像,我圈出了两个弧线未对齐的位置:

​

​

这里是供参考的椭圆转换代码,它只是对椭圆段进行2n次采样,其中n是所需的弧数。然后使用Keeper的3点圆弧函数,为每组3点绘制圆弧。

代码语言:javascript
复制
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对象转换为图形的代码(它存储为起点、终点、中心点和半径):

代码语言:javascript
复制
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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-03 18:08:52

已解决:

问题是,我使用的是基于整数的Rectangle,而不是基于浮点数的RectangleF,后者在绘制圆弧时调用了缩小转换。

代码语言:javascript
复制
New System.Drawing.Rectangle(Arc.CenterPoint.X - Arc.Radius, Arc.CenterPoint.Y - Arc.Radius, Arc.Radius * 2, Arc.Radius * 2)

应更改为:

代码语言:javascript
复制
New System.Drawing.RectangleF(Arc.CenterPoint.X - Arc.Radius, Arc.CenterPoint.Y - Arc.Radius, Arc.Radius * 2, Arc.Radius * 2) 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15681849

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档