編集部分まで下にスクロールしてパート 2 を読む
そのため、指定された X 座標と Y 座標を使用してポリゴンを作成する必要があるプロジェクトに取り組んでいます。座標は論理的な順序で指定され、パスを作成します。パスの幅が [w] (たとえば 20 メートル) の場合、ポリゴンのすべての位置を計算する必要があります。線に幅がないことは誰もが知っています。
この画像は、私がやりたいことを少し説明しています:
黒い点はパスの位置で、X 座標と Y 座標がわかっています。赤い線の幅は既知で、すべて [w] です (たとえば、20 メートル、パスは中央でそれらを切断します)。
すべての紫色の点の X、Y 位置を取得する方法がわかりません。緑の多角形を作成するために必要です。
これらの位置を C++ で計算するにはどうすればよいですか? 簡単にする機能はありますか?
PS: ご覧のとおり、赤い線は 2 本の青い線の角度の半分で角度を付けられています。
編集:
Visual Basic .NET で視覚化アプリを作成し、C++ に移植できる式を取得しました。まだ 1 つの問題があります。この画像を見てください。
(アプリのダウンロードリンク: http://gpb.googlecode.com/files/DRAWER2.zip )
問題は、パスが曲がると、ポリゴンのポイントが作成される側が逆になることです。これにより、破損したポリゴンが作成されます (または、必要な効果が得られません)。
コードは次のようになります。
Dim MainImage As New DynamicBitmap
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim temp As New DynamicBitmap
MainImage.CreateGrid(500, 500, 1, 1)
temp.LoadBitmap("map.jpg")
MainImage.DrawOnSurface(temp.Bitmap, temp.Rectangle, MainImage.Rectangle)
MainImage.Surface.DrawLine(Pens.Black, 0, 250, 500, 250)
MainImage.Surface.DrawLine(Pens.Black, 250, 0, 250, 500)
PictureBox1.Image = MainImage.Bitmap
PictureBox1.Refresh()
End Sub
Dim CPG(0) As Point
Dim CurrCount As Integer = 0
Dim Distance As Double = 30.0
Function CalculatePositions(ByVal PointStart As Point, ByVal PointMiddle As Point, ByVal PointEnd As Point) As Point()
Dim DeltaX As Double
Dim DeltaY As Double
Dim AdderX As Double
Dim AdderY As Double
Dim Length As Double
Dim CP(9) As Point
CP(0) = PointMiddle
CP(1) = PointStart
CP(2) = PointEnd
Dim RetP(1) As Point
DeltaX = CP(1).X - CP(0).X
DeltaY = CP(1).Y - CP(0).Y
Length = Math.Sqrt(((DeltaX * DeltaX) + (DeltaY * DeltaY))) + 0.0000000001
AdderX = (DeltaX / Length)
AdderY = (DeltaY / Length)
CP(3).X = (CP(0).X + (AdderX * Distance))
CP(3).Y = (CP(0).Y + (AdderY * Distance))
DeltaX = CP(2).X - CP(0).X
DeltaY = CP(2).Y - CP(0).Y
Length = Math.Sqrt(((DeltaX * DeltaX) + (DeltaY * DeltaY))) + 0.0000000001
AdderX = (DeltaX / Length)
AdderY = (DeltaY / Length)
CP(4).X = (CP(0).X + (AdderX * Distance))
CP(4).Y = (CP(0).Y + (AdderY * Distance))
DeltaX = CP(3).X - CP(4).X
DeltaY = CP(3).Y - CP(4).Y
Length = Math.Sqrt(((DeltaX * DeltaX) + (DeltaY * DeltaY))) + 0.0000000001
AdderX = (DeltaX / Length)
AdderY = (DeltaY / Length)
CP(8).X = (CP(4).X + (AdderX * Length / 2.0))
CP(8).Y = (CP(4).Y + (AdderY * Length / 2.0))
DeltaX = CP(8).X - CP(0).X
DeltaY = CP(8).Y - CP(0).Y
Length = Math.Sqrt(((DeltaX * DeltaX) + (DeltaY * DeltaY))) + 0.0000000001
AdderX = (DeltaX / Length)
AdderY = (DeltaY / Length)
CP(7).X = (CP(0).X - (AdderX * Distance))
CP(7).Y = (CP(0).Y - (AdderY * Distance))
CP(9).X = (CP(0).X + (AdderX * Distance))
CP(9).Y = (CP(0).Y + (AdderY * Distance))
MainImage.Surface.DrawLine(Pens.Red, New Point(CP(7).X - 3, CP(7).Y - 3), New Point(CP(7).X + 3, CP(7).Y + 3))
MainImage.Surface.DrawLine(Pens.Red, New Point(CP(7).X + 3, CP(7).Y - 3), New Point(CP(7).X - 3, CP(7).Y + 3))
MainImage.Surface.DrawLine(Pens.Blue, New Point(CP(9).X - 3, CP(9).Y - 3), New Point(CP(9).X + 3, CP(9).Y + 3))
MainImage.Surface.DrawLine(Pens.Blue, New Point(CP(9).X + 3, CP(9).Y - 3), New Point(CP(9).X - 3, CP(9).Y + 3))
Return RetP
End Function
Private Sub PictureBox1_Click(sender As System.Object, e As System.EventArgs) Handles PictureBox1.Click
'MsgBox(DirectCast(e, MouseEventArgs).X.ToString() + ":" + DirectCast(e, MouseEventArgs).Y.ToString())
ReDim Preserve CPG(CurrCount)
'i -= 1
CPG(CurrCount) = New Point(DirectCast(e, MouseEventArgs).X, DirectCast(e, MouseEventArgs).Y)
MainImage.Surface.DrawLine(Pens.Yellow, New Point(CPG(CurrCount).X - 3, CPG(CurrCount).Y - 3), New Point(CPG(CurrCount).X + 3, CPG(CurrCount).Y + 3))
MainImage.Surface.DrawLine(Pens.Yellow, New Point(CPG(CurrCount).X + 3, CPG(CurrCount).Y - 3), New Point(CPG(CurrCount).X - 3, CPG(CurrCount).Y + 3))
CurrCount += 1
If CurrCount = 1 Then
Else
If CurrCount = 2 Then
Dim DeltaX As Double
Dim DeltaY As Double
Dim AdderX As Double
Dim AdderY As Double
Dim Length As Double
DeltaX = CPG(CurrCount - 2).X - CPG(CurrCount - 1).X
DeltaY = CPG(CurrCount - 2).Y - CPG(CurrCount - 1).Y
Length = Math.Sqrt(((DeltaX * DeltaX) + (DeltaY * DeltaY))) + 0.0000000001
AdderX = (DeltaX / Length)
AdderY = (DeltaY / Length)
Dim Temp(1) As Point
Dim Angle01 As Double = Math.Atan2(CPG(CurrCount - 1).X - CPG(CurrCount - 2).X, CPG(CurrCount - 1).Y - CPG(CurrCount - 2).Y) * 180.0 / Math.PI
Dim SinMin As Double
Dim CosMin As Double
SinMin = Math.Sin(((-Angle01) + 0.0) / 180.0 * Math.PI)
CosMin = Math.Cos(((-Angle01) + 0.0) / 180.0 * Math.PI)
Temp(0).X = CPG(CurrCount - 2).X + (CosMin * Distance) + AdderX * Distance
Temp(0).Y = CPG(CurrCount - 2).Y + (SinMin * Distance) + AdderY * Distance
Temp(1).X = CPG(CurrCount - 2).X - (CosMin * Distance) + AdderX * Distance
Temp(1).Y = CPG(CurrCount - 2).Y - (SinMin * Distance) + AdderY * Distance
MainImage.Surface.DrawLine(Pens.Red, New Point(Temp(0).X - 3, Temp(0).Y - 3), New Point(Temp(0).X + 3, Temp(0).Y + 3))
MainImage.Surface.DrawLine(Pens.Red, New Point(Temp(0).X + 3, Temp(0).Y - 3), New Point(Temp(0).X - 3, Temp(0).Y + 3))
MainImage.Surface.DrawLine(Pens.Blue, New Point(Temp(1).X - 3, Temp(1).Y - 3), New Point(Temp(1).X + 3, Temp(1).Y + 3))
MainImage.Surface.DrawLine(Pens.Blue, New Point(Temp(1).X + 3, Temp(1).Y - 3), New Point(Temp(1).X - 3, Temp(1).Y + 3))
End If
MainImage.Surface.DrawLine(Pens.Blue, CPG(CurrCount - 2), CPG(CurrCount - 1))
If CurrCount > 2 Then
CalculatePositions(CPG(CurrCount - 3), CPG(CurrCount - 2), CPG(CurrCount - 1))
End If
End If
PictureBox1.Image = MainImage.Bitmap
PictureBox1.Refresh()
'MsgBox(CP(i).ToString())
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim DeltaX As Double
Dim DeltaY As Double
Dim AdderX As Double
Dim AdderY As Double
Dim Length As Double
DeltaX = CPG(CurrCount - 2).X - CPG(CurrCount - 1).X
DeltaY = CPG(CurrCount - 2).Y - CPG(CurrCount - 1).Y
Length = Math.Sqrt(((DeltaX * DeltaX) + (DeltaY * DeltaY))) + 0.0000000001
AdderX = (DeltaX / Length)
AdderY = (DeltaY / Length)
Dim Temp(1) As Point
Dim Angle01 As Double = Math.Atan2(CPG(CurrCount - 1).X - CPG(CurrCount - 2).X, CPG(CurrCount - 1).Y - CPG(CurrCount - 2).Y) * 180.0 / Math.PI
Dim SinMin As Double
Dim CosMin As Double
SinMin = Math.Sin(((-Angle01) + 0.0) / 180.0 * Math.PI)
CosMin = Math.Cos(((-Angle01) + 0.0) / 180.0 * Math.PI)
Temp(0).X = CPG(CurrCount - 1).X + (CosMin * Distance) - AdderX * Distance
Temp(0).Y = CPG(CurrCount - 1).Y + (SinMin * Distance) - AdderY * Distance
Temp(1).X = CPG(CurrCount - 1).X - (CosMin * Distance) - AdderX * Distance
Temp(1).Y = CPG(CurrCount - 1).Y - (SinMin * Distance) - AdderY * Distance
MainImage.Surface.DrawLine(Pens.Red, New Point(Temp(0).X - 3, Temp(0).Y - 3), New Point(Temp(0).X + 3, Temp(0).Y + 3))
MainImage.Surface.DrawLine(Pens.Red, New Point(Temp(0).X + 3, Temp(0).Y - 3), New Point(Temp(0).X - 3, Temp(0).Y + 3))
MainImage.Surface.DrawLine(Pens.Blue, New Point(Temp(1).X - 3, Temp(1).Y - 3), New Point(Temp(1).X + 3, Temp(1).Y + 3))
MainImage.Surface.DrawLine(Pens.Blue, New Point(Temp(1).X + 3, Temp(1).Y - 3), New Point(Temp(1).X - 3, Temp(1).Y + 3))
PictureBox1.Image = MainImage.Bitmap
PictureBox1.Refresh()
End Sub
この問題を解決するにはどうすればよいですか? 片側に赤いX-es、反対側に青いX-esが必要で、パスがどのように曲がるかに依存しないようにしたい. これを達成する方法は?