Я создаю парсер DXF для использования промышленным роботом. Робот может двигаться только по линиям и дугам, поэтому мне пришлось разложить объекты эллипса на ряд биарков (благодаря Keeper для функции дуги). Преобразование работает отлично, но когда я пытаюсь нарисовать дуги как путь на холсте, некоторые из них смещены.Biarc Rendering
Я знаю, что эти дуги действительно котангенс, так как в противном случае мой алгоритм группировки контуров сделал бы их отдельными путями, поэтому это определенно проблема отображения (я также проверил начальные точки и конечные точки вручную и подтвердил это). Я также экспортировал серию биарков, используя тот же метод, но вручную из SolidWorks и столкнулся с той же проблемой.
Вот изображение выходного сигнала на форме, я кружил где biarcs неровные:
Вот код преобразования Эллипс для справки, это просто дискретизацию сегмент эллипса 2n
раз, где n
- количество желаемых дуг. Затем, используя 3-точечную дуговую функцию на Keeper, она рисует дуги для каждого набора из трех точек.
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
Это код, который преобразует объект Дуга для графики (она хранится в качестве кузницы кадров, конечной точки, центральной точки и радиуса):
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
Есть ли решение этой проблемы, или это неотъемлемая проблема отображения?
@LarsTech Спасибо за уборку. – Crazymoomin