Приведенное ниже решение создает формулу для линии, которая проходит через указанную точку и пересекает границу прямоугольника под указанным углом.В зависимости от угла я проверяю, пересекается ли он с одной из двух границ прямоугольника.Я всегда основываю чек под углом от 0 до 90 градусов.Чтобы учесть это, тест в квадрантах Q2 и Q4 использует линию, которая перпендикулярна линии в Q1 и Q4.
Когда угол = 0, линия указывает на восток.
Я вычелугол от 360, так что линия вращается по часовой стрелке, а не против часовой стрелки.
Private Function GetIntersectionPoint(ByVal rectangleSize As SizeF, ByVal p As Point, ByVal degreeAngle As Single) As PointF
Dim w = CInt(rectangleSize.Width)
Dim h = CInt(rectangleSize.Height)
degreeAngle = ((360 - degreeAngle) Mod 360)
If degreeAngle = 0 Then
Return New Point(w, p.Y)
ElseIf degreeAngle = 90 Then
Return New Point(p.X, 0)
ElseIf degreeAngle = 180 Then
Return New Point(0, p.Y)
ElseIf degreeAngle = 270 Then
Return New Point(p.X, h)
End If
Dim x, y As Integer
If (degreeAngle > 0 AndAlso degreeAngle < 90) Then
y = YFromX(degreeAngle, w, p)
If y <= 0 AndAlso y >= -h Then
Return New Point(w, -y)
End If
x = XFromY(degreeAngle, 0, p)
Return New Point(x, 0)
End If
If (degreeAngle > 90 AndAlso degreeAngle < 180) Then
degreeAngle -= 90
y = YFromX_Perpedicular(degreeAngle, 0, p)
If y <= 0 AndAlso y >= -h Then
Return New Point(0, -y)
End If
x = XFromY_Perpendicular(degreeAngle, 0, p)
Return New Point(x, 0)
End If
If (degreeAngle > 180 AndAlso degreeAngle < 270) Then
degreeAngle -= 180
y = YFromX(degreeAngle, 0, p)
If y <= 0 AndAlso y >= -h Then
Return New Point(0, -y)
End If
x = XFromY(degreeAngle, -h, p)
Return New Point(x, h)
End If
If (degreeAngle > 270 AndAlso degreeAngle < 360) Then
degreeAngle -= 270
y = YFromX_Perpedicular(degreeAngle, w, p)
If y <= 0 AndAlso y >= -h Then
Return New Point(w, -y)
End If
x = XFromY_Perpendicular(degreeAngle, -h, p)
Return New Point(x, h)
End If
End Function
Private Function YFromX(ByVal degreeAngle As Single, ByVal x As Integer, ByVal p As Point) As Integer
Dim alpha As Double = degreeAngle * Math.PI / 180
Dim sinAlpha = Sin(alpha)
Dim cosAlpha = Cos(alpha)
Return CInt(sinAlpha / cosAlpha * (x - p.X) - p.Y)
End Function
Private Function XFromY(ByVal degreeAngle As Single, ByVal y As Integer, ByVal p As Point) As Integer
Dim alpha As Double = degreeAngle * Math.PI / 180
Dim sinAlpha = Sin(alpha)
Dim cosAlpha = Cos(alpha)
Return CInt(cosAlpha / sinAlpha * (y + p.Y) + p.X)
End Function
Private Function YFromX_Perpedicular(ByVal degreeAngle As Single, ByVal x As Integer, ByVal p As Point) As Integer
Dim alpha As Double = degreeAngle * Math.PI / 180
Dim sinAlpha = Sin(alpha)
Dim cosAlpha = Cos(alpha)
Return CInt((cosAlpha / sinAlpha) * (p.X - x) - p.Y)
End Function
Private Function XFromY_Perpendicular(ByVal degreeAngle As Single, ByVal y As Integer, ByVal p As Point) As Integer
Dim alpha As Double = degreeAngle * Math.PI / 180
Dim sinAlpha = Sin(alpha)
Dim cosAlpha = Cos(alpha)
Return CInt(p.X - sinAlpha / cosAlpha * (y + p.Y))
End Function