Повернуть вектор нормали на плоскость оси
у меня есть набор точек данных в 3D-пространстве, которые, по-видимому, все попадают на определенную плоскость. Я использую PCA для вычисления параметров плоскости. 3-я составляющая PCA дает мне нормальный вектор плоскости (самая слабая составляющая).
что я хочу сделать дальше, это преобразовать все точки на указанную плоскость и посмотреть на нее в 2D.
моя идея состояла в том, чтобы сделать следующее:
- найти центральную точку (среднюю точку) на плоскости
- вычесть его из всех точек данных расположить их вокруг источника
- Поверните Нормаль так, чтобы она стала (0,0, -1)
- применить это вращение ко всем точкам данных
- используйте ортогональную проекцию (в основном, пропустите ось z)
теперь я застрял в поиске правильной операции вращения. Я попытался работать с acos или atan и настроить две матрицы вращения. Кажется, оба метода (используя acos, используя atan) дают мне неправильный результат. Возможно, вы сможете мне помочь сюда!
код Matlab следует:
b = atan(n(1) / n(2));
rotb = [cos(b) -sin(b) 0; sin(b) cos(b) 0; 0 0 1];
n2 = n * rotb;
a = atan(n(1) / n(3));
rota = [cos(a) 0 sin(a); 0 1 0; -sin(a) 0 cos(a)];
n3 = n2 * rotaows:
Я жду n2
иметь y-компоненту нуля. Однако это уже не удается для вектора (-0.6367, 0.7697, 0.0467).
3 ответов
Если у вас есть плоскость, у вас есть нормальный вектор и начало координат. Я бы вообще не делал никаких" поворотов". Вы всего в нескольких векторных операциях от вашего ответа.
- давайте назовем нормальным вектором вашей плоскости новую ось Z.
- вы можете создать новую ось y, пересекая старую ось x с новой осью z (Нормаль вашей плоскости).
- создайте новую ось x, пересекая новый z с новым y.
- сделайте все ваши новые векторы оси в единичные векторы (длины 1).
- для каждой точки у вас есть, создайте вектор, который от вашего нового происхождения до точки (векторное вычитание point - plane_origin). Просто поставьте точки с новыми векторами X и Y, и вы получите пару (x, y), которую вы можете построить!
Если у вас уже есть перекрестные и точечные функции продукта, это всего лишь несколько строк кода. Я знаю, что это работает, потому что большинство 3D-видеоигр, которые я написал, работали таким образом.
хитрости:
- платить внимание, на какие направления указывают ваши векторы. Если они указывают неправильный путь, отрицают результирующий вектор или изменяют порядок перекрестного произведения.
- у вас есть проблемы, если нормальная плоскость точно такая же, как Ваша исходная ось X.
Как насчет:
разложите нормальный вектор на вектор в плоскости XY и вектор Z. Затем примените вращение вокруг оси Z, чтобы выровнять вектор XY с одной из осей. Затем найдите точечное произведение нормали с осью Z и поверните вдоль которой когда-либо из X,Y вы выстроились.
идея состоит в том, чтобы выровнять нормальный вектор с Z, и, сделав это, ваша плоскость теперь является плоскостью XY.
хотя были и другие интересные ответы, это мы выяснили, пока жду ответов:
function roti = magic_cosini(n)
b = acos(n(2) / sqrt(n(1)*n(1) + n(2)*n(2)));
bwinkel = b * 360 / 2 / pi;
if (n(1) >= 0)
rotb = [cos(-b) -sin(-b) 0; sin(-b) cos(-b) 0; 0 0 1];
else
rotb = [cos(-b) sin(-b) 0; -sin(-b) cos(-b) 0; 0 0 1];
end
n2 = n * rotb;
a = acos(n2(3) / sqrt(n2(2)*n2(2) + n2(3)*n2(3)));
awinkel = a * 360 / 2 / pi;
rota = [1 0 0; 0 cos(-a) -sin(-a); 0 sin(-a) cos(-a)];
roti = rotb * rota;
(он возвращает, надеюсь, правильную матрицу двойного вращения)
недостаток, который мы имели раньше и исправили здесь, был esp. рассмотрим знак компонента X, который не был охвачен косинусными вычислениями. Это заставило нас повернуть в неправильном направлении (вращение на 180° - угол).
Я надеюсь, что я также найду время, чтобы попробовать Решение Nosredna это! Всегда полезно избегать тригонометрии.