Как повернуть трехмерную плоскую стенку к стене?
Я работаю с данными 3D-сетки, где у меня много 3D-треугольников, которые мне нужно повернуть, чтобы устранить значение Z, преобразовав его в 2D-треугольник.
С этим 2D треугольником я делаю некоторые векторные вычисления.
После того, как я закончу свою работу, мне нужно повернуть ее обратно на исходный угол так, чтобы старые точки вернулись в исходное положение, чтобы вернуться в трехмерную сетку.
Изменить: это код, который я использую.
Я не могу понять, как изменить направление вращения.
входные
var p1:Object, p2:Object, p3:Object;
Найти лицо нормальное
var norm:Object = calcNormal(p1,p2,p3);
Найти углы поворота на основе нормального
sinteta = -norm.y / Math.sqrt(norm.x * norm.x + norm.y * norm.y);
costeta = norm.x / Math.sqrt(norm.x * norm.x + norm.y * norm.y);
sinfi = -Math.sqrt(norm.x * norm.x + norm.y * norm.y);
cosfi = norm.z;
Поверните вокруг Z, а затем Y, чтобы выровнять по плоскости z.
lx = costeta * cosfi;
ly = -sinteta * cosfi;
lz = sinfi;
mx = sinteta;
my = costeta;
mz = 0;
nx = -sinfi * costeta;
ny = sinfi * sinteta;
nz = cosfi;
var np1:Object = {};
np1.x=p1.x*lx + p1.y*ly + p1.z*lz;
np1.y=p1.x*mx + p1.y*my + p1.z*mz;
np1.z=p1.x*nx + p1.y*ny + p1.z*nz;
var np2:Object = {};
np2.x=p2.x*lx + p2.y*ly + p2.z*lz;
np2.y=p2.x*mx + p2.y*my + p2.z*mz;
np2.z=p2.x*nx + p2.y*ny + p2.z*nz;
var np3:Object = {};
np3.x=p3.x*lx + p3.y*ly + p3.z*lz;
np3.y=p3.x*mx + p3.y*my + p3.z*mz;
np3.z=p3.x*nx + p3.y*ny + p3.z*nz;
2 ответа
Определите нормаль плоскости, используя уравнение плоскости. Затем определите кватернион, представляющий вращение нормали к оси z. Поверните многоугольник, сделайте свою работу и поверните его обратно.
Вектор можно повернуть на кватернион, создав кватернион из вектора, где 'w' = 0:
v = (x, y, z) q = (w = 0, x, y, z)
Чтобы повернуть на q2,
rv = q2 * q * q2 ^ -1
Чтобы преобразовать rv в точку, опустите w (который равен 0).
Чтобы повернуть назад снова, используйте
q2 ^ -1 * rv * q
где q2 ^ -1 - обратное или сопряженное к q2.
РЕДАКТИРОВАТЬ 2
Аплодисменты для кода C++, но вот как работают мои классы Vector3d и Quaternion (упрощенно):
class Vector3d {
//...
double x, y, z;
//...
// functions here e.g. dot (dot product), cross (cross product)
};
class Quaternion {
//...
double w, x, y, z;
//...
Quaternion inverse() const { // also equal to conjugate for unit quaternions
return Quaternion (w, -x, -y, -z);
}
static Quaternion align(const Vector3d v1, const Vector3d v2) {
Vector3d bisector = (v1 + v2).normalize();
double cosHalfAngle = v1.dot(bisector);
Vector3d cross;
if(cosHalfAngle == 0.0) {
cross = v1.cross(bisector);
} else {
cross = v1.cross(Vector3d(v2.z, v2.x, v2.y)).normalize();
}
return Quaternion(cosHalfAngle, cross.x, cross.y, cross.z);
}
Quaternion operator *(const Quaternion &q) const {
Quaternion r;
r.w = w * q.w - x * q.x - y * q.y - z * q.z;
r.x = w * q.x + x * q.w + y * q.z - z * q.y;
r.y = w * q.y + y * q.w + z * q.x - x * q.z;
r.z = w * q.z + z * q.w + x * q.y - y * q.x;
return r;
}
};
Таким образом, используя этот вид математики, идея состоит в том, что вы создаете кватерион, используя метод 'align', который представляет вращение от плоскости, перпендикулярной оси z (т.е. v1 - плоскость, нормализованная [нормализованная], v2 - вектор единицы z-оси) - давайте назовем это Q. Чтобы повернуть каждую точку p, вы должны создать кватернион q для этой точки, повернуть ее qr, а затем преобразовать q обратно в точку p2, вот так:
q = Quaternion(0, p.x, p.y, p.z);
qr = Q * q * Q.inverse();
p2 = Vector3d(qr.x, qr.y, qr.z);
Чтобы снова повернуть p2, выполните:
q = Quaternion(0, p2.x, p2.y, p2.z);
qr = Q.inverse() * q * Q;
p = Vector3d(qr.x, qr.y, qr.z);
Вращение треугольника - почти наверняка неправильный подход. Если ваше намерение состоит в том, чтобы изменить треугольник, то вы должны просто выполнить операции в его текущей (3d) системе координат. Если ваше намерение не состоит в том, чтобы изменить треугольник, вам не нужно поворачивать его обратно. Если вы не знаете, как выполнять операции, которые вы хотите выполнять в текущей системе координат, задайте этот вопрос.