2010-10-07 84 views
2

我試圖使用旋轉矩陣向量,但是糊塗了。如何在處理中使用矩陣旋轉向量?

我以爲所有我需要做的就是創建一個旋轉矩陣,並乘以一個向量,以獲得旋轉矢量。

Here你可以看到一個簡單的測試,我使用Processing做到:

processing text

使用一個遞增旋轉和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(); 
} 

處理帶有一個PVectorPMatrix3D我用它。

難道我不使用他們PMatrix應該使用或者這是一個錯誤? 任何提示?

回答

3

這是罪魁禍首:

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; 

將解決此問題。

+0

這就是它!嗚呼!謝謝! – 2010-10-08 08:52:48

3

相反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