如何在处理中使用矩阵旋转向量?
问题描述:
我试图使用旋转矩阵向量,但是糊涂了。如何在处理中使用矩阵旋转向量?
我以为所有我需要做的就是创建一个旋转矩阵,并乘以一个向量,以获得旋转矢量。
Here你可以看到一个简单的测试,我使用Processing做到:
使用一个递增旋转和X/Y/Z来改变轴。
这里是源:
PVector[] clone,face = {new PVector(50,0,50),new PVector(-50,0,50),new PVector(-50, 0, -50),new PVector(50, 0, -50)};
color faceC = color(255,0,0),cloneC = color(0,255,0);
float angle = 90;
PVector x = new PVector(1,0,0),y = new PVector(0,1,0),z = new PVector(0,0,1), axis = x;
PFont ocr;
void setup(){
size(400,400,P3D);
strokeWeight(1.1610855);smooth();
clone = rotateVerts(face,angle,axis);
ocr = loadFont("ocr.vlw");
}
void draw(){
background(255);
fill(0);textFont(ocr,10);text("a = increment rotation\nx/y/z = change axis\nrotation: " + angle + "\naxis: " + axis,10,10,200,200);fill(255);
translate(width*.5,height*.5);
rotateX(map(mouseY,height*.5,-height*.5,0,TWO_PI));
rotateY(map(mouseX,0,width,0,TWO_PI));
drawQuad(face,faceC);
drawQuad(clone,cloneC);
stroke(128,0,0);line(0,0,0,100,0,0);stroke(0,128,0);line(0,0,0,0,-100,0);stroke(0,0,128);line(0,0,0,0,0,100);
}
void keyPressed(){
if(key == 'a') angle += 15;
if(angle > 360) angle -= 360;
if(key == 'x') axis = x;
if(key == 'y') axis = y;
if(key == 'z') axis = z;
clone = rotateVerts(face,angle,axis);
}
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] = PVector.add(verts[i],new PVector());
//rotate using a matrix
PMatrix3D rMat = new PMatrix3D();
rMat.rotate(radians(angle),axis.x,axis.y,axis.z);
for(int i = 0; i<vl;i++) rMat.mult(clone[i],clone[i]);
return clone;
}
void drawQuad(PVector[] verts,color c){
stroke(c);
beginShape(QUADS);
for(int i = 0 ; i < 4; i++) vertex(verts[i].x,verts[i].y,verts[i].z);
endShape();
}
难道我不使用他们PMatrix应该使用或者这是一个错误? 任何提示?
答
这是罪魁祸首:
rMat.mult(clone[i],clone[i]);
这是不是安全的做法,因为不像C或Java中,源正在改变,因为操作进行。
改变功能的结尾:
PVector[] dst = new PVector[vl];
for(int i = 0; i<vl;i++) dst[i] = new PVector();
for(int i = 0; i<vl;i++) rMat.mult(clone[i],dst[i]);
return dst;
将解决此问题。
答
相反PVector的,你也可以使用toxiclibs几何类,这将有助于简化整个语法颇有几分:
import toxi.geom.*;
Vec3D[] rotateVerts(Vec3D[] verts, float angle, Vec3D axis){
Vec3D[] clone = new Vec3D[verts.length];
for(int i = 0; i<verts.length;i++)
clone[i] = verts[i].getRotatedAroundAxis(axis,angle);
return clone;
}
或使用矩阵做转换:
Vec3D[] rotateVerts(Vec3D[] verts, float angle, Vec3D axis){
Matrix4x4 mat=new Matrix4x4();
mat.rotateAroundAxis(axis,angle);
Vec3D[] clone = new Vec3D[verts.length];
for(int i = 0; i<verts.length;i++) clone[i] = mat.applyTo(verts[i]);
return clone;
}
仅仅是简单的轴旋转,后者会稍微慢一些,但如果您同时进行其他转换(例如平移等)则更有意义。此外,在两种情况下,angle
被假定为弧度......
希望帮助!
+0
非常好!谢谢!我正在浏览文档(https://dev.postspectacular.com/docs/core/toxi/geom/Vec3D.html#headingXY()),并发现相当方便的标题XY,XZ,YZ。如果我有4个顶点和一个法线,我怎样才能在Z轴上旋转?如果我用正常的标题方法,Z永远是一样的,因为我处理1个顶点。任何提示? – 2010-10-08 21:56:41
这就是它!呜呼!谢谢! – 2010-10-08 08:52:48