Найти единичный вектор точно на полпути между двумя соединенными отрезками

8

Похоже, быстрый и простой вопрос, но я не смог найти именно то, что я ищу, так:

Как рассчитать вектор единичной длины, который указывает вдоль линии, которая составляет точно 50% угла двух соединенных отрезков линии?

Картинка говорит тысячи слов (что также лучше, чем моё объяснение!). Пример единичного вектора, разделяющего два соединенных отрезка линии
Поэтому в основном я хочу вычислить синий единичный вектор с учетом двух отрезков красной линии (которые на самом деле представляют собой 3 точки и поэтому гарантированно будут соединены)

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

Любые примеры были бы идеальными в C ++, но другие языки приветствуются.

Большое спасибо за любые указатели.

Адам Нейлор
источник

Ответы:

13

Создайте и нормализуйте два вектора из вашего красного сегмента, начиная с их общей вершины, затем добавьте результаты (компонент за компонентом). Затем вы можете нормализовать вывод, если вы хотите получить единичный вектор.

Проблема в том, что вы всегда окажетесь во втором случае, потому что угол между 2 векторами всегда будет меньше 180 °. Но тогда, конечно, вы можете просто создать противоположный вектор и посмотреть, какой из них лучше подходит вашей цели.

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

XGouchet
источник
Отлично, я думаю, это именно то, что я ищу! Я знал, что это было легко :) Я оставлю это открытым, чтобы посмотреть, какие еще ответы я получу ... Спасибо
Адам Нейлор,
Я собирался написать более сложный метод, включающий точечный продукт, хотя раньше я использовал этот простой метод, черт!
CiscoIPPhone
Что вы подразумеваете под «проблема в том, что вы всегда будете в конечном итоге это второй случай»?
CiscoIPPhone
@CiscoIPPhone Я думаю, он ссылается на мою диаграмму. Решение для точечного продукта более чем приветствуется CiscoIPPhone, по крайней мере, я дам ему +1 :)
Адам Нейлор,
На самом деле я ссылался на ваш образ. Используя точечное произведение, вы можете получить угол между двумя векторами, но опять-таки он останется ниже 180 °.
XGouchet
1

Я думаю, что вы можете получить направление, чтобы быть последовательным, рассматривая это, как будто вы генерируете 2D нормаль вершины. Это:

  1. Возьмите каждый из красных векторов, поменяйте местами компоненты x и y и отрицайте один из них, чтобы создать нормали.

  2. Нормализуй их.

  3. Суммируйте эти два вектора и перенормируйте.

Вы, вероятно, также захотите проверить случай, когда две красные линии перекрывают друг друга - окончательная перенормировка попытается разделить на ноль.

Адам
источник
Спасибо Адам, у этого подхода есть имя? Я хотел бы изучить это подробнее ...
Адам Нейлор
Не то, что я знаю из. Трюк с генерацией нормальных векторов объясняется на stackoverflow.com/questions/1243614/…
Адам
0

Пусть A и B будут вашими векторами:

результат

Векторы суммирования не обязательно должны быть единичными векторами, а просто равными по длине, поэтому, если | A | > = | B |, вы можете:

эквивалентный результат

который является более численно устойчивым, так как у вас есть только дробь и больший знаменатель

как работает сумма

Тот же результат можно получить вычитанием, еще раз векторы должны быть равны по длине

Это работает только для невыпуклых углов; Вы можете просто проверить, является ли ваш угол выпуклым, и умножить H на -1

FXIII
источник
Я не думаю, что это сработает, если | A | ! = | B | ... рассмотрим A = [0,1] B = [100,0], результат не [.707, .707]
Ричард Фабиан
@Richard Fabian Вы правы, я забыл неравенство треугольника!
FxIII