Я бы пошел на это, сравнив отношение компонентов вашего вектора, который также является наклоном линии, параллельной вектору, к той же величине для вектора, указывающего от центра прямоугольника к его углу. Это говорит вам, попадает ли вектор в горизонтальную или вертикальную сторону. После этого вы можете использовать простую пропорциональность, чтобы найти точку пересечения.
Предположим, ваш вектор (x,y)
, и на данный момент предположим, что обе координаты положительны. Наклон равен y/x
, а эквивалентное количество для прямоугольника равно h/w
с использованием системы координат, в которой центр прямоугольника находится в (0,0)
. Теперь, если y/x > h/w
, ваша точка пересечения будет на верхнем крае, поэтому вы знаете, что ее высота равна h / 2. Затем вы можете вычислить координаты как (0.5*h*x/y,0.5*h)
. Если y/x < h/w
, точка пересечения находится на правом краю, а координаты (0.5*w,0.5*w*y/x)
.
Чтобы использовать это на практике, вы бы хотели на самом деле сделать сравнение между y*w
и x*h
, чтобы избежать проблем с делением на ноль и избежать относительно дорогого оператора деления (не то, что это действительно много разницы). Кроме того, вы можете найти правильные знаки для компонентов точки пересечения, просто используя знаки x
и y
. Так что в коде это будет выглядеть примерно так:
def intersect_perimeter(x, y, w, h):
if abs(y*w) > abs(x*h):
return (0.5*h*x/abs(y), 0.5*h*sign(y))
else:
return (0.5*w*sign(x), 0.5*w*y/abs(x))
(непроверенные). Это потерпит неудачу, если x
равно нулю и либо y
, либо w
равно нулю, но в этом случае у вас либо нулевой вектор (и проблема не определена), либо прямоугольник нулевой ширины (опять же, проблема в том, что не определено). Так что я бы не стал проверять ошибки в этом случае.
Если ваш прямоугольник центрируется в точке, отличной от (0,0)
, вам просто нужно добавить вектор положения, представляющий центр прямоугольника, к результату этой функции.