向下滚动到编辑以阅读第 2 部分
所以我正在做一个项目,我需要使用给定的 X 和 Y 坐标创建一个多边形。以逻辑顺序给定坐标并创建路径。现在我需要计算一个 poligon 的所有位置,如果路径宽度为 [w](例如 20 米)。我们都知道线条没有宽度。
这张图片解释了我想要做的事情:
黑点是路径的位置,它们的 X 和 Y 坐标是已知的。红线的宽度是已知的,它们都是[w](例如20米,路径将它们从中间切开)。
我不知道如何获得所有紫色点的 X、Y 位置。我需要它们,这样我就可以创建绿色多边形形状。
如何在 C++ 中计算这些位置?有没有让它更容易的功能?
PS:如您所见,红线与两条蓝线夹角的一半成角度。
编辑:
我在 Visual Basic .NET 中创建了一个可视化应用程序,并获得了可以移植到 C++ 的公式。还有一个问题,请看这张图:
(应用下载链接: 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,并且我希望它不依赖于路径的转弯方式。如何做到这一点?