get closest point to a line

后端 未结 12 2003
逝去的感伤
逝去的感伤 2020-11-28 04:45

I\'d like to have a straight forward C# function to get a closest point (from a point P) to a line-segment, AB. An abstract function may look like this. I\'ve search through

12条回答
  •  鱼传尺愫
    2020-11-28 05:10

    This is the right algorythm to get nearest point of a segment from a point(Tested)(vb.net)

    s2 = ClosestPointToSegment(point_x, Point_y, Segment_start_x, Segment_start_y, Segment_end_X, Segment_end_Y)
    
    Public Shared Function DistanceTo(x1 As Double, y1 As Double, x2 As Double, y2 As Double) As Double
        Return Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2))
    End Function
    
    
    Public Shared Function DistanceTo(point_x As Double, point_y As Double, lineStart_x As Double, lineStart_y As Double, lineEnd_x As Double, lineEnd_y As Double) As Double
        Dim tI As Double = ((lineEnd_x - lineStart_x) * (point_x - lineStart_x) + (lineEnd_y - lineStart_y) * (point_y - lineStart_x)) / Math.Pow(DistanceTo(lineStart_x, lineStart_y, lineEnd_x, lineEnd_y), 2)
        Dim dP As Double = ((lineEnd_x - lineStart_x) * (point_y - lineStart_y) - (lineEnd_y - lineStart_y) * (point_x - lineStart_x)) / DistanceTo(lineStart_x, lineStart_y, lineEnd_x, lineEnd_y)
    
        If tI >= 0R AndAlso tI <= 1.0R Then
            Return Math.Abs(dP)
        Else
            Return Math.Min(DistanceTo(point_x, point_y, lineStart_x, lineStart_y), DistanceTo(point_x, point_y, lineEnd_x, lineEnd_y))
        End If
    End Function
    Private Shared Function ClosestPointToSegment(P_x As Double, p_y As Double, A_x As Double, a_y As Double, B_x As Double, b_y As Double) As Double()
        Dim a_to_p As PointF = New PointF(), a_to_b As PointF = New PointF()
        Dim rikthex As Double, rikthey As Double
        Dim s1(1) As Double
        Dim p1_v1_X As Double, p1_v1_y As Double, distanca1 As Double, distanca2 As Double
        a_to_p.X = P_x - A_x
        a_to_p.Y = p_y - a_y
        a_to_b.X = B_x - A_x
        a_to_b.Y = b_y - a_y
        Dim atb2 As Single = a_to_b.X * a_to_b.X + a_to_b.Y * a_to_b.Y
        Dim atp_dot_atb As Single = a_to_p.X * a_to_b.X + a_to_p.Y * a_to_b.Y
        Dim t As Single = atp_dot_atb / atb2
        rikthex = A_x + a_to_b.X * t
        rikthey = a_y + a_to_b.Y * t
        If A_x > B_x Then
            If rikthex < A_x And rikthex > B_x Then 'pika duhet ne rregulll
                If a_y > b_y Then
                    If rikthey < a_y And rikthey > b_y Then 'pika duhet ne rregulll
    
                    Else
                        distanca1 = DistanceTo(P_x, p_y, A_x, a_y)
                        distanca2 = DistanceTo(P_x, p_y, B_x, b_y)
                        If distanca1 < distanca2 Then
                            rikthex = A_x
                            rikthey = a_y
                        Else
                            rikthex = B_x
                            rikthey = b_y
                        End If
    
                    End If
                Else
                    If rikthey > a_y And rikthey < b_y Then 'pika duhet ne rregulll
    
                    Else
                        distanca1 = DistanceTo(P_x, p_y, A_x, a_y)
                        distanca2 = DistanceTo(P_x, p_y, B_x, b_y)
                        If distanca1 < distanca2 Then
                            rikthex = A_x
                            rikthey = a_y
                        Else
                            rikthex = B_x
                            rikthey = b_y
                        End If
    
                    End If
    
                End If
            Else
                distanca1 = DistanceTo(P_x, p_y, A_x, a_y)
                distanca2 = DistanceTo(P_x, p_y, B_x, b_y)
                If distanca1 < distanca2 Then
                    rikthex = A_x
                    rikthey = a_y
                Else
                    rikthex = B_x
                    rikthey = b_y
                End If
            End If
        Else
            If rikthex > A_x And rikthex < B_x Then 'pika duhet ne rregulll
                If a_y > b_y Then
                    If rikthey < a_y And rikthey > b_y Then 'pika duhet ne rregulll
    
                    Else
                        distanca1 = DistanceTo(P_x, p_y, A_x, a_y)
                        distanca2 = DistanceTo(P_x, p_y, B_x, b_y)
                        If distanca1 < distanca2 Then
                            rikthex = A_x
                            rikthey = a_y
                        Else
                            rikthex = B_x
                            rikthey = b_y
                        End If
    
                    End If
                Else
                    If rikthey > a_y And rikthey < b_y Then 'pika duhet ne rregulll
    
                    Else
                        distanca1 = DistanceTo(P_x, p_y, A_x, a_y)
                        distanca2 = DistanceTo(P_x, p_y, B_x, b_y)
                        If distanca1 < distanca2 Then
                            rikthex = A_x
                            rikthey = a_y
                        Else
                            rikthex = B_x
                            rikthey = b_y
                        End If
    
                    End If
    
                End If
            Else
                distanca1 = DistanceTo(P_x, p_y, A_x, a_y)
                distanca2 = DistanceTo(P_x, p_y, B_x, b_y)
                If distanca1 < distanca2 Then
                    rikthex = A_x
                    rikthey = a_y
                Else
                    rikthex = B_x
                    rikthey = b_y
                End If
            End If
        End If
        s1(0) = rikthex
        s1(1) = rikthey
        Return s1
    
    End Function
    

提交回复
热议问题