i have a picture fram.
and a line.
i need to tell when the two hit each other.
the problem is that the picture has a left and top
but the line has y1 y2 x1 x2.
i have been trying to work it out for ages
could someone help me plese.
The picture frame is box with 4 corners, where each can be represented as an (X, Y) pair according to the following table
Upper Left Corner = (Box.Left, Box.Top)
Upper Right Corner = (Box.Left+Box.Width-1, Box.Top)
Lower Left Corner = (Box.Left, Box.Top+Box.Height-1)
Lower Right Corner = (Box.Left+Box.Width-1, Box.Top+Box.Height-1
Thinking in terms of this frame: If I were to represent the top of the frame as a line, it would be a line from the upper left corner to the upper right corner.
The Top Line of the Frame from left to right
TopBorderLine.X1 = Box.Left
TopBorderLine.Y1 = Box.Top
TopBorderLine.X2 = Box.Left + Box.Width - 1
TopBorderLine.Y2 = Box.Top
The Left Border of the Frame from top to bottom
LeftBorderLine.X1 = Box.Left
LeftBorderLine.Y1 = Box.Top
LeftBorderLine.X2 = Box.Left
LeftBorderLine.Y2 = Box.Top + Box.Height - 1
and the line has a starting point and an ending point, each can be represented as an (X, Y) pair as follows:
Start Point = (Line.X1, Line.Y1)
End Point = (Line.X2, Line.Y2)
And now it become a line intersection problem.
Good Luck
-------------- As a circle of light increases so does the circumference of darkness around it. - Albert Einstein
==========================================================
Yes, so we have a line intersection problem.
You have thee possible senarios.
1) The Line is Horizontal
2) The Line is Vertical
3) The Line is Diagonal
I will address the third case - the diagonal line.
a) Get the Bottom and Right edges of the frame, and get the Left, Top, Bottom, and Right edges of the line. Order the coordinates of the line will be needed in range checking later on
Dim FrameRight as Long
Dim FrameBottom as Long
dim LineLeft as Long
dim LineTop as Long
dim LineRight as Long
dim LineBottom as Long
If (Line.X1 < Line.X2) Then
LineLeft = Line.X1
LineRight = Line.X2
Else
LineLeft = Line.X2
LineRight = Line.Y1
Endif
If (Line.Y1 < Line.Y2) Then
LineBottom = Line.Y1
LineTop = Line.Y2
Else
LineBottom = Line.Y2
LineTop = Line.Y1
End If
b) Determin the slope of the diagonal line.
dim Slope as Double
Slope = (Line.Y2 - Line.Y1) / (Line.X2 - Line.X1)
Calculate the X Coordinate of the Top Border Intersection. The Y Coordinate is already known (Frame.Top)
XInter = (Frame.Top - Line.Y1 + (Slope * Line.X1)) / Slope
But since we're dealing with a line segment, we need to insure that its within the segment of the Top Frame. Since the diagonal line is also only a segment, we need to verify its 'range' as well.
If ((XInter >= Frame.Left) and (XInter <= FrameRight)) Then
If (Frame.Top >= LineBottom) and (Frame.Top <= LineTop)) Then
<We Intersect as coordinate pair (XInter, Frame.Top)>
Else
<No Intersection with Top Border>
Endif
Else
<No Intersection with Top Border>
Endif
To check for intersection with the bottom is almost the same, but instead of Frame.Top, we use FrameBottom
XInter = (FrameBottom - Line.Y1 + (Slope * Line.X1)) / Slope
If ((XInter >= Frame.Left) and (XInter <= FrameRight)) Then
If (FrameBottom >= LineBottom) and (FrameBottom <= LineTop)) Then
<We Intersect as coordinate pair (XInter, FrameBottom)>
Else
<No Intersection with Top Border>
Endif
Else
<No Intersection with Top Border>
Endif
Now we need to check for Left and Right Intersections.
For the Left Border Intersection, the X Coordinate is known (Frame.Left), so we need to calculate the Y Intersection
YInter = (Slope * (Frame.Left - Line.X1)) + Line.Y1
Now again check our segment ranges
If ((YInter >= FrameBottom) and (YInter <= Frame.Top)) Then
If ((Frame.Left >= LineLeft) and (Frame.Left <= LineRight))
<We Intersect at Coordinate (Frame.Left, YInter)>
Else
<No Intersection>
End If
Else
<No Intersection>
Endif
Now for the Right Border
YInter = (Slope * (FrameRight - Line.X1)) + Line.Y1
If ((YInter >= FrameBottom) and (YInter <= Frame.Top)) Then
If ((FrameRight >= LineLeft) and (FrameRight <= LineRight))
<We Intersect at Coordinate (FrameRight, YInter)>
Else
<No Intersection>
End If
Else
<No Intersection>
Endif
If I've made a mistake in my algebra, I apologize in advance, but I will certainly help work it out.
The Horizontal and Line checks need to happen before you do the diagonal process. If you need help with those, let me know
Good Luck
-------------- As a circle of light increases so does the circumference of darkness around it. - Albert Einstein
Here is what I think should work for all cases, I have made a couple of changes for the sake of efficiency, I have removed the no intersection references, if you don't hit an intersection point, then you don't have one, and I have added the code to handle the horizontal and vertical line cases.
Dim FrameRight As Long
Dim FrameBottom As Long
Dim LineLeft As Long
Dim LineTop As Long
Dim LineRight As Long
Dim LineBottom As Long
Dim CaseType As Integer
Dim Slope As Double
Dim OverLapStart As Long
Dim OverLapEnd As Long
Dim XInter As Long
Dim YInter As Long
CaseType = 3 ' Assume Diagonal Line
If (Line.X1 < Line.X2) Then
LineLeft = Line.X1
LineRight = Line.X2
Else
LineLeft = Line.X2
LineRight = Line.Y1
If (Line.X1 = Line.X2) Then
CaseType = 2 ' Line is Vertical
End If
End If
If (Line.Y1 < Line.Y2) Then
LineBottom = Line.Y1
LineTop = Line.Y2
Else
LineBottom = Line.Y2
LineTop = Line.Y1
If (Line.Y1 = Line.Y2) Then
CaseType = 1 ' Line is Horizontal
End If
End If
Select Case CaseType
Case 1 ' Horizontal Line
If ((Frame.Left >= LineLeft) And (Frame.Left <= LineRight)) Then
' <We Intersect Left at Coordinate (Frame.Left, Line.Y1) >
End If
If ((FrameRight >= LineLeft) And (FrameRight <= LineRight)) Then
' <We Intersect Right at Coordinate (FrameRight, Line.Y1) >
End If
If ((Frame.Left <= LineRight) And (FrameRight >= LineLeft)) Then
If (Line.Y1 = Frame.Top) Then
OverLapStart = Max(Frame.Left, LineLeft)
OverLapEnd = Min(FrameRight, LineRight)
' <We Overlap Top from OverLapStart to OverLapEnd
Else
If (Line.Y1 = FrameBottom) Then
OverLapStart = Max(Frame.Left, LineLeft)
OverLapEnd = Min(FrameRight, LineRight)
' <We Overlap Bottom from OverLapStart to OverLapEnd
End If
End If
End If
Case 2 ' Vertical Line
If ((Frame.Top >= LineBottom) And (Frame.Top <= LineTop)) Then
' <We Intersect Top at Coordinate (Line.X2, Frame.Top) >
End If
If ((FrameBottom >= LineBottom) And (FrameBottom <= LineTop)) Then
' <We Intersect Bottom at Coordinate (Line.X2, FrameBottom) >
End If
If ((FrameBottom <= LineTop) And (Frame.Top >= LineBottom)) Then
If (Line.X1 = Frame.Left) Then
OverLapStart = Max(FrameBottom, LineBottom)
OverLapEnd = Min(Frame.Top, LineRight)
' <We Overlap Left from OverLapStart to OverLapEnd
Else
If (Line.X1 = FrameRight) Then
OverLapStart = Max(FrameBottom, LineBottom)
OverLapEnd = Min(Frame.Top, LineRight)
' <We Overlap Right from OverLapStart to OverLapEnd
End If
End If
End If
Case 3 ' Diagonal Line
Slope = (Line.Y2 - Line.Y1) / (Line.X2 - Line.X1)
' Check for Top Border Intersection
If ((Frame.Top >= LineBottom) And (Frame.Top <= LineTop)) Then
XInter = ((Frame.Top - Line.Y1) / Slope) + Line.X1
If ((XInter >= Frame.Left) And (XInter <= FrameRight)) Then
' <We Intersect Top at coordinate (XInter, Frame.Top) >
End If
End If
' Check for Bottom Border Intersection
If ((FrameBottom >= LineBottom) And (FrameBottom <= LineTop)) Then
XInter = ((FrameBottom - Line.Y1) / Slope) + Line.X1
If ((XInter >= Frame.Left) And (XInter <= FrameRight)) Then
' <We Intersect Bottom at coordinate (XInter, FrameBottom) >
End If
End If
' Check for Left Border Intersection
If ((Frame.Left >= LineLeft) And (Frame.Left <= LineRight)) Then
YInter = (Slope * (Frame.Left - Line.X1)) + Line.Y1
If ((YInter >= FrameBottom) And (YInter <= Frame.Top)) Then
' <We Intersect Left at Coordinate (Frame.Left, YInter) >
End If
End If
' Check for Right Border Intersection
If ((FrameRight >= LineLeft) And (FrameRight <= LineRight)) Then
YInter = (Slope * (FrameRight - Line.X1)) + Line.Y1
If ((YInter >= FrameBottom) And (YInter <= Frame.Top)) Then
' <We Intersect Right at Coordinate (FrameRight, YInter) >
End If
End If
End Select
Private Function Max(Value1 As Long, value2 As Long) As Long
Max = IIf(Value1 > value2, Value1, value2)
End Function
Private Function Min(Value1 As Long, value2 As Long) As Long
Min = IIf(Value1 < value2, Value1, value2)
End Function
-----
I probably will not be back on-line until Monday, so I wish you well. I will check the board on Monday
Good Luck
-------------- As a circle of light increases so does the circumference of darkness around it. - Albert Einstein
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.