1

産業用ロボットで使用する DXF パーサーを作成しています。ロボットは線と円弧でしか移動できないため、楕円エンティティを一連の 2 つの円弧に分解する必要がありました (円弧機能のKeeperに感謝します)。変換は完全に機能しますが、キャンバス上で円弧をパスとして描画しようとすると、一部がずれます。

これらの円弧は実際にはコタンジェントであることを知っています。そうしないと、輪郭のグループ化アルゴリズムによって別々のパスが作成されるため、これは間違いなく表示上の問題です (開始点と終了点も手動で確認し、これを確認しました)。また、同じ方法を使用して一連のバイアークをエクスポートしましたが、SolidWorks から手動でエクスポートしたところ、同じ問題が発生しました。

これはフォームの出力のイメージです。バイアークがずれている場所を丸で囲みました。

ここに画像の説明を入力

参照用の楕円変換コードは次のとおりです。楕円のセグメント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

この問題の解決策はありますか、それとも固有の表示の問題ですか?

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 に答える