Как спроецировать точку на плоскость в 3D? - PullRequest
57 голосов
/ 07 марта 2012

У меня есть 3D-точка (point_x, point_y, point_z), и я хочу проецировать ее на 2D-плоскость в 3D-пространстве, которая (плоскость) определяется координатами точки (orig_x, orig_y, orig_z) и унарным перпендикуляром вектор (normal_dx, normal_dy, normal_dz).

Как мне справиться с этим? enter image description here

Ответы [ 7 ]

76 голосов
/ 07 марта 2012

1) Создайте вектор из вашей orig точки к точке интереса:

v = point-orig (in each dimension);

2) Возьмите скалярное произведение этого вектора с единичным вектором нормалей n:

dist = vx*nx + vy*ny + vz*nz; dist = скалярное расстояние от точки к плоскости вдоль нормали

3) Умножьте единичный вектор нормали на расстояние и вычтите этот вектор из вашей точки.

projected_point = point - dist*normal;

Редактировать с изображением: Я немного изменил твою картинку. Красный - v; v точка normal = длина синего и зеленого (dist выше). Синий normal*dist. Green = blue * -1: чтобы найти planar_xyz, начните с point и добавьте зеленый вектор.

enter image description here

38 голосов
/ 15 июля 2013

Это действительно легко, все, что вам нужно сделать, это найти перпендикулярное (здесь сокращение |_) расстояние от точки P до плоскости, затем перевести P назад по перпендикулярному расстоянию в направлении нормали плоскости . В результате получается перевод P в плоскости.

Возьмем простой пример (который мы можем проверить путем проверки):

Установить n = (0,1,0) и P = (10,20, -5).

enter image description here

Прогнозируемая точка должна быть (10,10, -5). Из проверки вы можете видеть, что Pproj находится в 10 единицах перпендикулярно плоскости, и если бы она была в плоскости, она имела бы y = 10.

Так как мы можем найти это аналитически?

Плоское уравнение: Ax + By + Cz + d = 0. Это уравнение означает "для того, чтобы точка (x, y, z) находилась на плоскости, она должна удовлетворять Ax + By + Cz + d = 0" .

Что такое уравнение Ax + By + Cz + d = 0 для плоскости, нарисованной выше?

Самолет имеет нормальное n = (0,1,0). Для определения d просто используйте контрольную точку , уже находящуюся в плоскости :

(0)x + (1)y + (0)z + d = 0

Точка (0,10,0) находится на плоскости. Подключив выше, находим, d = -10. Тогда уравнение плоскости будет 0x + 1y + 0z - 10 = 0 (если вы упростите, вы получите y = 10).

Хорошая интерпретация d состоит в том, что она говорит о перпендикулярном расстоянии , которое вам потребуется для перемещения плоскости вдоль ее нормали, чтобы плоскость проходила через начало координат .

В любом случае, когда у нас есть d, мы можем найти расстояние _ _ любой точки до плоскости по следующему уравнению:

enter image description here

Существует 3 возможных класса результатов для | _ расстояния до плоскости:

  • 0: НА САМОЛЕТЕ ТОЧНО (почти никогда не бывает с ошибками с плавающей запятой)
  • + 1:> 0: ВПЕРЕД плоскости (на нормальной стороне)
  • -1: <0: позади самолета (на противоположной стороне нормального) </li>

Во всяком случае,

enter image description here

Что вы можете проверить на правильность путем проверки на диаграмме выше

10 голосов
/ 27 января 2017

Этот ответ является дополнением к двум существующим ответам. Я стремлюсь показать, как объяснения @tmpearce и @bobobobo сводятся к одному и тому же, и в то же время дают быстрые ответы тем, кто просто заинтересован в копировании уравнения, лучше всего подходящего для их ситуации.

Метод для плоскостей, определенных нормальными n и точкой o

Этот метод был объяснен в ответе @ tmpearce.

При заданном точечном-нормальном определении плоскости с нормалью n и точкой o на плоскости, точка p ' , будучи точкой на плоскости, ближайшей к данной точке p , можно найти по:

1) p '= p - ( n ⋅ ( p - o )) * п

Метод для плоскостей, определенных нормальными n и скалярными d

Этот метод был объяснен в ответе @ bobobobo.

Учитывая плоскость, определенную нормальным n и скалярным d , точка p ', являющаяся точкой на плоскости, ближайшей к данной точке p , можно найти по:

2) p '= p - ( n p + d ) * п

Если вместо этого у вас есть точка-нормальное определение плоскости (плоскость определяется нормалью n и точкой o на плоскости) @bobobobo предлагает найти d :

3) d = - n o

и вставить это в уравнение 2. Это дает:

4) p '= p - ( n p - n o ) * n

Примечание о разнице

. Более подробно рассмотрим уравнения 1 и 4. Сравнивая их, вы увидите, что уравнение 1 использует n ⋅ ( p - o ), где В уравнении 2 используется n p - n o . На самом деле это два способа записать одно и то же:

5) n ⋅ ( p - o ) = n p - n o = n p + d

Таким образом, можно выбрать интерпретацию скаляра d , как если бы это был «предварительный расчет». Я объясню: если известны плоскости n и o , но o используется только для вычисления n ⋅ ( р - о ), мы можем также определить плоскость как n и d и вычислить n p + d вместо этого, потому что мы только что видели, что это то же самое.

Дополнительно для программирования с использованием d имеет два преимущества:

  1. Поиск p 'теперь более простой расчет, особенно для компьютеров. Для сравнения:
    • с использованием n и o : 3 вычитания + 3 умножения + 2 сложения
    • с использованием n и d : 0 вычитаний + 3 умножения + 3 сложения.
  2. Использование d ограничивает определение плоскости только 4 действительными числами (3 для n + 1 для d ) вместо 6 (3 для n + 3 для o ). Это экономит ⅓ памяти.
10 голосов
/ 07 марта 2012

Недостаточно указать только начало плоскости и вектор нормали.Это действительно определяет плоскость 3d, однако это не определяет систему координат на плоскости.

Подумайте, что вы можете повернуть плоскость вокруг вектора нормали относительно его начала (то есть поместить вектор нормали в начало координат и "повернуть").

Однако вы можете найти расстояниеспроецированная точка на начало координат (которая, очевидно, не зависит от поворота).

Вычтите начало координат из 3d-точки.Затем сделайте перекрестное произведение с нормальным направлением.Если ваш нормальный вектор нормализован - длина результирующего вектора равна требуемому значению.

РЕДАКТИРОВАТЬ

Для полного ответа потребуется дополнительный параметр.Скажем, вы предоставляете также вектор, который обозначает ось X на вашей плоскости.Итак, у нас есть векторы n и x .Предположим, они нормализованы.

Начало координат обозначено O , ваша 3D-точка равна p .

Тогда ваша точка проецируетсяследующие:

x = ( p - O ) точка x

y = ( p - O ) точка ( n крестик x )

1 голос
/ 08 марта 2012

Я думаю, вы должны немного изменить способ описания самолета. Действительно, лучший способ описать плоскость - это вектор n и скаляр c

( x , n ) = c

(абсолютное значение) константы c представляет собой расстояние плоскости от начала координат и равно ( P , n ), где P - любая точка на плоскости.

Итак, пусть P будет вашей orig точкой, а A 'будет проекцией новой точки A на плоскость. Что вам нужно сделать, это найти a такой, что A '= A - * n удовлетворяет уравнению плоскости, что есть

( A - * n , n ) = ( P , n )

Решая вопрос, вы обнаружите, что

a = ( A , n ) - ( P , n ) = ( A , n ) - c

, что дает

A '= A - [( A , n ) - c] n

Используя ваши имена, это читается как

c = orig_x*normal_dx + orig_y*normal_dy+orig_z*normal_dz;
a = point_x*normal_dx + point_y*normal_dy + point_z*normal_dz - c;
planar_x = point_x - a*normal_dx;
planar_y = point_y - a*normal_dy;
planar_z = point_z - a*normal_dz;

Примечание: ваш код сохранит один скалярный продукт, если вместо orig point P вы сохраните c = ( P , n ), что означает в основном на 25% меньше флопов для каждой проекции (в случае, если эта процедура используется в вашем коде много раз).

1 голос
/ 07 марта 2012

Пусть V = (orig_x, orig_y, orig_z) - (point_x, point_y, point_z)

N = (normal_dx, normal_dy, normal_dz)

Пусть d = V.dotproduct (N);

спроецированная точка P = V + dN

0 голосов
/ 10 сентября 2014

Пусть r будет точкой для проецирования, а p будет результатом проекции. Пусть c - любая точка на плоскости, а n - нормаль к плоскости (необязательно нормализованная). Напишите p = r + m d для некоторого скаляра m, который будет выглядеть неопределенным, если их решение не является решением. Так как ( p - c ). n = 0, поскольку все точки на плоскости удовлетворяют этому ограничению, которое есть у каждого ( r - c ). n + m ( d . n ) = 0 и, следовательно, m = [( c - r ). n ] / [ d . n ], где используется скалярное произведение (.). Но если d . n = 0, решения не существует. Например, если d и n перпендикулярны друг другу, решение недоступно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...