|
|
Title | See if the user clicked on a Line control |
Description | |
Keywords | distance, point-to-line, line-to-line, point, line, Line control, click |
Categories | Algorithms, Controls |
|
|
Thanks to Steve Redmond for pointing out a bug in this code.
Check the distance between the point clicked and each Line on the form. If the closest Line is within 60 twips of the mouse, select that Line.
|
|
' Calculate the distance between the point and the segment.
Private Function DistToSegment(ByVal px As Single, ByVal py _
As Single, ByVal X1 As Single, ByVal Y1 As Single, _
ByVal X2 As Single, ByVal Y2 As Single) As Single
Dim dx As Single
Dim dy As Single
Dim t As Single
dx = X2 - X1
dy = Y2 - Y1
If dx = 0 And dy = 0 Then
' It's a point not a line segment.
dx = px - X1
dy = py - Y1
DistToSegment = Sqr(dx * dx + dy * dy)
Exit Function
End If
t = (px + py - X1 - Y1) / (dx + dy)
If t < 0 Then
dx = px - X1
dy = py - Y1
ElseIf t > 1 Then
dx = px - X2
dy = py - Y2
Else
X2 = X1 + t * dx
Y2 = Y1 + t * dy
dx = px - X2
dy = py - Y2
End If
DistToSegment = Sqr(dx * dx + dy * dy)
End Function
' See if the user clicked on a segment.
Private Sub Form_MouseUp(Button As Integer, Shift As _
Integer, X As Single, Y As Single)
' Maximum distance that counts as a hit.
Const MAX_HIT_DIST = 60
Dim i As Integer
Dim best_i As Integer
Dim best_dist As Single
Dim dist As Single
' Deselect the previously selected segment.
If m_SelectedSegment >= 0 Then
With Line1(m_SelectedSegment)
.BorderColor = vbBlack
.BorderWidth = 1
End With
m_SelectedSegment = -1
End If
' See which segment is closest to the mouse.
best_dist = MAX_HIT_DIST + 1
For i = Line1.LBound To Line1.UBound
With Line1(i)
dist = DistToSegment(X, Y, .X1, .Y1, .X2, .Y2)
If dist < best_dist Then
best_dist = dist
best_i = i
End If
End With
Next i
' See if this is close enough.
If best_dist <= MAX_HIT_DIST Then
m_SelectedSegment = best_i
With Line1(m_SelectedSegment)
.BorderColor = vbRed
.BorderWidth = 3
End With
End If
End Sub
|
|
|
|
|
|