Как найти точку по периметру прямоугольника? - PullRequest
0 голосов
/ 24 февраля 2012

Я использую Python 2.7 и Pygame, но подойдет любой языковой ответ.

Я пытаюсь найти заданную точку вдоль вектора в периметре прямоугольника.Я знаю вектор и центр, ширину и высоту прямоугольника, но центр может быть (0, 0) ради простоты

Так, например, я хочу найти точку в периметре прямоугольникаследуя за вектором примерно (0.7, 0.7) прямоугольника, который имеет ширину 2 и высоту 6.

Теперь работает то, что у меня есть;но должен быть лучший, более элегантный способ: я беру длину более широкого значения между высотой и шириной прямоугольника и использую каждое число между этим и 0 и проверяю это по каждой из 4 сторонпрямоугольник и посмотрите, есть ли в нем.

Это код, который я использую специально для моей игры, не обобщенный вообще: http://pastebin.com/8Ai1iQeL

Ответы [ 2 ]

1 голос
/ 24 февраля 2012

Я бы пошел на это, сравнив отношение компонентов вашего вектора, который также является наклоном линии, параллельной вектору, к той же величине для вектора, указывающего от центра прямоугольника к его углу. Это говорит вам, попадает ли вектор в горизонтальную или вертикальную сторону. После этого вы можете использовать простую пропорциональность, чтобы найти точку пересечения.

Предположим, ваш вектор (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), вам просто нужно добавить вектор положения, представляющий центр прямоугольника, к результату этой функции.

1 голос
/ 24 февраля 2012

Я собираюсь сделать это для векторов в верхнем правом квадранте, но не должно быть сложно обобщить это для других. Вы знаете угол вектора и длину сторон прямоугольника. Итак

1) Определите, будет ли вектор ударять по правой стороне или вершине прямоугольника. Сделайте это, построив прямоугольный треугольник, гипотенуза которого является диагональю прямоугольника, то есть линия от начала координат до верхнего угла. Если угол A вектора больше этого угла, он достигнет вершины; в противном случае он ударит в сторону.

2) Предположим, что он ударяет в сторону (решение будет аналогичным, если он достигнет вершины). Если ширина треугольника равна w, то вы можете построить прямоугольный треугольник, вершинами которого являются начало координат, точка (w / 2, 0) и точка (w / 2, y), где (w / 2, y ) это точка, которую вы хотите найти. Тогда просто используйте закон синусов , чтобы получить y.

Как написано, это решение включает в себя некоторое ветвление (4 x 2), чтобы покрыть все возможности, но я уверен, что если вы поработаете с ним, вы сможете найти способы устранения дублирования кода. Например, вначале вы можете просто повернуть каждый вектор в верхний правый квадрант, а затем после решения использовать вращение, чтобы восстановить правильное местоположение точки.

...