Matrix 3D旋转矩阵在Processing/Java中随时间变形

Matrix 3D旋转矩阵在Processing/Java中随时间变形,matrix,rotation,processing,transformation,Matrix,Rotation,Processing,Transformation,我正在做一个项目,我想生成一个3D网格来表示一定数量的数据 为了创建这个网格,我想使用变换矩阵,所以我创建了一个基于几个网站上的数学算法的类 一切似乎都正常,缩放/平移,但只要我在x轴上旋转网格,它就会在2到3次完整旋转后开始变形。感觉我的缩放值在增加,这会变换我的网格。我为这个问题挣扎了几天,但我不知道出了什么问题 为了让事情更清楚,你可以下载我的完整设置 我定义了一个框的坐标,并在将它们写入屏幕之前将它们通过转换矩阵 这是旋转物体的公式 void-appendRotation(浮动角度、浮动

我正在做一个项目,我想生成一个3D网格来表示一定数量的数据

为了创建这个网格,我想使用变换矩阵,所以我创建了一个基于几个网站上的数学算法的类

一切似乎都正常,缩放/平移,但只要我在x轴上旋转网格,它就会在2到3次完整旋转后开始变形。感觉我的缩放值在增加,这会变换我的网格。我为这个问题挣扎了几天,但我不知道出了什么问题

为了让事情更清楚,你可以下载我的完整设置

我定义了一个框的坐标,并在将它们写入屏幕之前将它们通过转换矩阵

这是旋转物体的公式

void-appendRotation(浮动角度、浮动角度、浮动角度、浮动角度、PVector角度){
布尔setPivot=false;
如果(inPivot.x!=0 | | inPivot.y!=0 | | inPivot.z!=0){
setPivot=true;
}
//如果setPivot=true,则平移位置
if(setPivot){
//不同轴的平移需要设置不同
如果(inPivot.x!=0){this.appendTranslation(inPivot.x,0,0);}
如果(inPivot.y!=0){this.appendTranslation(0,inPivot.y,0);}
如果(inPivot.z!=0){this.appendTranslation(0,0,inPivot.z);}
}
//创建旋转矩阵
矩阵x3d旋转矩阵=新矩阵x3d();
//xsin en xcos
float xSinCal=sin(弧度(inXAngle));
浮点数xCosCal=cos(弧度(inXAngle));
//赖氨酸
浮动ySinCal=sin(弧度(inYAngle));
浮动yCosCal=cos(弧度(因扬格尔));
//zsin en zcos
浮点数zSinCal=sin(弧度(inZAngle));
浮点数zCosCal=cos(弧度(inZAngle));
//绕x旋转
旋转矩阵。setIdentity();
// --
旋转矩阵。矩阵[1][1]=xCosCal;
旋转矩阵。矩阵[1][2]=X增量;
旋转矩阵。矩阵[2][1]=-x增量;
旋转矩阵。矩阵[2][2]=xCosCal;
//向基础矩阵添加旋转
这个。乘以(旋转矩阵);
//绕y旋转
旋转矩阵。setIdentity();
// --
旋转矩阵。矩阵[0][0]=yCosCal;
旋转矩阵。矩阵[0][2]=-ySinCal;
旋转矩阵。矩阵[2][0]=ySinCal;
旋转矩阵。矩阵[2][2]=yCosCal;
//向基础矩阵添加旋转
这个。乘以(旋转矩阵);
//绕z旋转
旋转矩阵。setIdentity();
// --
旋转矩阵。矩阵[0][0]=zCosCal;
旋转矩阵。矩阵[0][1]=zSinCal;
旋转矩阵。矩阵[1][0]=-zSinCal;
旋转矩阵。矩阵[1][1]=zCosCal;
//向基础矩阵添加旋转
这个。乘以(旋转矩阵);
//解译位置
if(setPivot){
//不同轴的平移需要设置不同
如果(inPivot.x!=0){this.appendTranslation(-inPivot.x,0,0);}
如果(inPivot.y!=0){this.appendTranslation(0,-inPivot.y,0);}
如果(inPivot.z!=0){this.appendTranslation(0,0,-inPivot.z);}
}
}

有人有线索吗?

你永远不想累计变换矩阵。这将在矩阵中引入错误,并导致缩放或倾斜正交组件等问题


正确的方法是跟踪累计俯仰角、偏航角和横滚角。然后在每次更新时从这些角度重建变换矩阵。

您永远不希望累积变换矩阵。这将在矩阵中引入错误,并导致缩放或倾斜正交组件等问题


正确的方法是跟踪累计俯仰角、偏航角和横滚角。然后每次更新都从这些角度重建变换矩阵。

如果有机会:避免乘以旋转矩阵。跟踪累积旋转,并在每一步计算一个新的旋转矩阵

如果无法避免与旋转矩阵相乘,则将它们相乘(第16页)。对于我来说,它可以进行一万多次乘法

然而,我怀疑这不会对你有帮助,数字错误通常需要两个以上的步骤才能显现出来。在我看来,你出现问题的原因似乎在别的地方

偏航、俯仰和横摇不适合任意旋转。欧拉角存在奇异性和不稳定性。看38:25(大卫·萨克斯的演讲)


祝你好运

如果有机会:避免与旋转矩阵相乘。跟踪累积旋转,并在每一步计算一个新的旋转矩阵

如果无法避免与旋转矩阵相乘,则将它们相乘(第16页)。对于我来说,它可以进行一万多次乘法

然而,我怀疑这不会对你有帮助,数字错误通常需要两个以上的步骤才能显现出来。在我看来,你出现问题的原因似乎在别的地方

偏航、俯仰和横摇不适合任意旋转。欧拉角存在奇异性和不稳定性。看38:25(大卫·萨克斯的演讲)


祝你好运

正如@don提到的,尽量避免累积转换,因为您可能会遇到各种各样的问题。一次旋转一个轴可能会导致问题。尝试一次完成所有旋转

另外,请记住,Processing附带了它自己的Matrix3D类,名为Matrix3D,该类有一个方法,该方法以角度(弧度)和x、y、z值作为旋转轴

下面是一个示例函数,该函数将旋转一组PVectors:

PVector[] rotateVerts(PVector[] verts,float angle,PVector axis){
  int vl = verts.length;
  PVector[] clone = new PVector[vl];
  for(int i = 0; i<vl;i++) clone[i] = verts[i].get();
  //rotate using a matrix
  PMatrix3D rMat = new PMatrix3D();
  rMat.rotate(angle,axis.x,axis.y,axis.z);
  PVector[] dst = new PVector[vl];
  for(int i = 0; i<vl;i++) {
    dst[i] = new PVector();
    rMat.mult(clone[i],dst[i]);
  }
  return dst;
}
PVector[]旋转顶点(PVector[]顶点、浮动角度、PVector轴){
int vl=垂直长度;
PVector[]克隆=新PVector[vl];
对于(inti=0;iAs@don
void setIdentity() {  
    this.matrix = identityMatrix;
}