Как повернуть трехмерную плоскую стенку к стене?

Я работаю с данными 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) системе координат. Если ваше намерение не состоит в том, чтобы изменить треугольник, вам не нужно поворачивать его обратно. Если вы не знаете, как выполнять операции, которые вы хотите выполнять в текущей системе координат, задайте этот вопрос.

Другие вопросы по тегам