Как спроецировать точку на плоскость в 3D?
У меня есть 3D-точка (point_x,point_y,point_z), и я хочу проецировать ее на 2D-плоскость в 3D-пространстве,которая (плоскость) определяется координатами точки (orig_x,orig_y,orig_z) и унарным перпендикулярным вектором (normal_dx, normal_dy, normal_dz).
Как я должен справиться с этим?
7 ответов:
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
и добавить зеленый вектор.
это действительно легко, все, что вам нужно сделать, это найти перпендикуляр (abbr здесь
|_
) расстояние от точкиP
к самолету, затем перевестиP
назад по перпендикуляру в направлении нормали к плоскости. В результате получается переводP
садится в самолет.принимая простой пример (что мы можем проверить с помощью инспекции):
установить n=(0,1,0), и P=(10,20, -5).
проекционная точка должна быть (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
, мы можем найти в |_ расстоянии любой укажите на плоскость по следующему уравнению:есть 3 возможных класса результатов для / _ расстояние до плоскости:
- 0: на плоскости точно (почти никогда не бывает с ошибками с плавающей точкой)
- +1: > 0: перед самолетом (ВКЛ нормальная сторона)
- -1:
в любом случае,
что вы можете проверить как правильно осмотром в диаграмме выше
недостаточно указать только начало координат плоскости и вектор нормали. Это определяет трехмерную плоскость, однако это не определяет систему координат на плоскости.
подумайте, что вы можете повернуть свою плоскость вокруг нормального вектора относительно его начала координат (т. е. поместить нормальный вектор в начало координат и "повернуть").
однако вы можете найти расстояние проецируемой точки до начала координат (которое, очевидно, инвариантно к вращение.)
вычесть начало координат из 3d точки. Затем сделайте поперечный продукт с нормальным направлением. Если ваш нормальный вектор нормализован-длина результирующего вектора равна необходимому значению.
EDIT
полный ответ потребует дополнительного параметра. Скажем, вы также предоставляете вектор, который обозначает ось x на вашей плоскости. Так что у нас есть векторы n и x. Предположим, что они нормированный.
начало координат обозначается O, ваша 3D точка p.
тогда ваша точка проецируется следующим образом:
x = (p -O), точка x
y = (p -O) точка (n крест x)
этот ответ является дополнением к двум существующим ответам. Я стремлюсь показать, как объяснения @tmpearce и @bobobobo сводятся к одному и тому же, в то же время предоставляя быстрые ответы тем, кто просто заинтересован в копировании уравнения, лучше всего подходящего для их ситуации.
метод для плоскостей, определяемых нормалью n и точки o
этот метод был объяснен в ответе @tmpearce.
дали точки-нормальное определение плоскости с нормалью n и точки o на плоскости, точки p', будучи точкой на плоскости, ближайшей к заданной точке p, можно найти на:
1) p'= p - (n ⋅ (p -o))*n
метод для плоскостей, определяемых нормалью n и скалярного d
этот метод был объяснен в ответе @bobobobo.
учитывая плоскость, определяемую нормалью n и скалярного d, точка p', будучи точкой на плоскости, ближайшей к заданной точке p, можно найти на:
2) p'= p - (n⋅ p + d)*n
Если вместо этого у вас есть получил точки-нормальное определение плоскости (плоскость определяется нормалью 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 ⋅ (p -o), мы также можем определить плоскость с помощью n и d и расчета n⋅ p + d вместо этого, потому что мы только что видели, что это то же самое.
дополнительно для программирования с помощью d имеет два преимущества:
- найти p' теперь это более простой расчет, особенно для компьютеров. Сравнивать:
- используя n и o: 3 вычитания + 3 умножение + 2 дополнения
- используя n и d: 0 вычитания + 3 умножения + 3 дополнения.
- используя d ограничивает определение плоскости только 4 вещественными числами (3 для n + 1 для d), вместо 6 (3 для n + 3 для o). Это экономит memory память.
пусть 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 + d. N
Я думаю, что вы должны немного изменить способ описания самолета. Действительно, лучший способ описать плоскость - через вектор n и скаляр c
( x,n)= c
(абсолютное значение) константа c является расстояние плоскости от начала координат, равен (P,n), где P любая точка на самолетик.
Итак, давайте P ваш ориг точка, а A' - проекция новой точки A на плоскость. Что вам нужно сделать, это найти a такое, что A'= A - a*n удовлетворяет уравнению плоскости, то есть
(A - a*n,n) = (P,n)
решение для a, вы найдете это
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;
Примечание: ваш код сохранит один скалярный продукт, если вместо ориг точка P вы магазине c=(P,n), т. е. на 25% меньше флоп для каждой проекции (в случае, если эта процедура используется много раз в коде).
пусть r быть точкой для проекта и p быть результатом проекции. Пусть c быть любой точкой на плоскости и пусть n быть нормалью к плоскости (не обязательно нормализованной). Пиши p = r + m d для некоторых скалярных m, которые будут рассматриваться как неопределенные, если их нет решения. Так как (p -c).n = 0, потому что все точки на плоскости удовлетворяют это ограничение имеет (r -c).n + m (d . n) = 0 и поэтому м = [(c -r).n] / [d.n], где скалярное произведение (.) предназначенный. Но если d.n = 0 решения не существует. Например, если d и n перпендикулярны друг к другу никакое решение не доступно.