Я бы это сделал, сравнив соотношение компонентов вашего вектора, которое также является наклонной линии, параллельной вектору, к той же величине для вектора, указывающего от центра прямоугольника до его угла. Это говорит вам, попадает ли вектор в горизонтальную или вертикальную сторону. После этого вы можете использовать простую пропорциональность, чтобы найти точку пересечения.
Предположим ваш вектор: (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)
, вам просто нужно добавить вектор положения, представляющий центр прямоугольника, к результату этой функции.
http://stackoverflow.com/search?q=line+intersection+rectangle –
Спасибо за ссылку, я не использовал эти термины, и кажется, что ваши результаты нашли лучшие результаты, почти лишив мой вопрос. Еще раз спасибо. – TankorSmash