如何旋转3D tringle平贴在墙上?墙上、tringle

2023-09-08 10:53:16 作者:纯天然野生帅哥

我正在与3D网格数据,在那里我有很多的3D三角形,我需要旋转,以消除Z值,将其转换为2D的三角形。

通过这种2D的三角形我正在做一些矢量计算。

在我与我的工作完成,我需要回到其旋转至原来的角度,这样老点返回到原来的位置,以适应回3D网格。

编辑:这是code,我使用 我无法弄清楚如何扭转旋转。

输入

  VAR P1:对象,P2:对象,P3:对象;
 
最新现代风公寓客厅设计图片效果图

查找脸上正常

  VAR规范:对象= 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;
我= costeta;
MZ = 0;

NX = -sinfi * costeta;
NY = sinfi * sinteta;
NZ = cosfi;

变种NP1:对象= {};
np1.x = p1.x * LX + p1.y * LY + p1.z * LZ;
np1.y = p1.x * MX + p1.y *我+ p1.z * MZ;
np1.z = p1.x * NX + p1.y *纽约+ p1.z * NZ;

变种NP2:对象= {};
np2.x = p2.x * LX + p2.y * LY + p2.z * LZ;
np2.y = p2.x * MX + p2.y *我+ p2.z * MZ;
np2.z = p2.x * NX + p2.y *纽约+ p2.z * NZ;

变种NP3:对象= {};
np3.x = p3.x * LX + p3.y * LY + p3.z * LZ;
np3.y = p3.x * MX + p3.y *我+ p3.z * MZ;
np3.z = p3.x * NX + p3.y *纽约+ p3.z * NZ;
 

解决方案

确定正常的飞机使用的平面方程。然后,确定四元的重新presents中的垂直于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

Appologies为C ++ code,但这里是如何我的Vector3D和四元数类工程(简体):

 类的Vector3D {
  // ...
  双X,Y,Z;
  // ...
  //此处的功能如点(点积),跨(跨产品)
};

四元数类{
  // ...
  双W,X,Y,Z;
  // ...
  四元数逆()const的{//也等于共轭的单位四元
    返回四元(瓦特,-x,-y,-z);
  }

  静态四元数对齐(常量的Vector3D V1,常量的Vector3D V2){
    的Vector3D平分线=(V1 + V2).normalize();
    双cosHalfAngle = v1.dot(平分);
    的Vector3D交叉;

    如果(cosHalfAngle == 0.0){
      跨= v1.cross(平分);
    } 其他 {
      跨= v1.cross(的Vector3D(v2.z,V2.X,v2.y))正常化()。
    }

    返回四元(cosHalfAngle,cross.x,cross.y,cross.z);
  }

  四元数运算符*(const的四元数放大器; Q)const的{
    四元数ř;

    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;

    返回ř;
  }
};
 

因此​​,使用这种数学的想法是,你创建一个使用该重新presents从平面垂直于Z轴旋转的对齐方法quaterion(即V1是平面的法[标准化] V2是Z轴单位向量) - 让呼叫Q.要旋转的每一点,对,你可以创建一个四元数,Q,对于这一点,旋转,QR,然后再转换q回点,P2,就像这样:

  Q =四元数(0,p.x,p.y,p.z);
QR = Q * Q * Q.inverse();
P2 =的Vector3D(qr.x,qr.y,qr.z);
 

要回来了旋转P2,这样做:

  Q =四元数(0,p2.x,p2.y,p2.z);
QR = Q.inverse()* Q * Q;
P =的Vector3D(qr.x,qr.y,qr.z);
 

I'm working with 3D mesh data, where I have lots of 3D triangles which I need to rotate to eliminate the Z value, converting it to a 2D triangle.

With this 2D triangle I'm doing some vector calculations.

After I'm done with my work I need to rotate it back to the original angle such that the old points return back to their original positions, to fit back into the 3D mesh.

Edit: This is the code I'm using. I can't figure out how to reverse the rotation.

Inputs

var p1:Object, p2:Object, p3:Object;

Find face normal

var norm:Object = calcNormal(p1,p2,p3);

Find rotation angles based on normal

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;

Rotate around Z and then Y to align to the z plane.

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;

解决方案

Determine the normal of the plane using the plane equation. Then, determine a quaternion that represents the rotation of the normal to the z axis. Rotate the polygon, do your work, and rotate it back.

A vector can be rotated by a quaternion by creating a quaternion from the vector where 'w' = 0:

v = (x, y, z) q = (w=0, x, y, z)

To rotate by q2,

rv = q2 * q * q2 ^ -1

To convert rv to a point, drop the w (which is 0).

To rotate back again, use

q2 ^ -1 * rv * q

where q2 ^ -1 is the inverse or conjugate of q2.

EDIT 2

Appologies for the C++ code, but here is how my Vector3d and Quaternion classes work (simplified):

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;
  }
};

So using this kind of maths, the idea is that you create a quaterion using the 'align' method which represents a rotation from the plane normal to the z axis (i.e. v1 is plane normal [normalized], v2 is z axis unit vector) - lets call that Q. To rotate each point, p, you would create a quaternion, q, for the point, rotate it, qr, then convert q back to a point, p2, like so:

q = Quaternion(0, p.x, p.y, p.z);
qr = Q * q * Q.inverse();
p2 = Vector3d(qr.x, qr.y, qr.z);

To rotate p2 back again, do:

q = Quaternion(0, p2.x, p2.y, p2.z);
qr = Q.inverse() * q * Q;
p = Vector3d(qr.x, qr.y, qr.z);