Определите нормаль плоскости, используя уравнение плоскости .Затем определите кватернион , представляющий вращение нормали к оси 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.
EDIT 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);