【问题标题】:How do I rotate vectors using matrices in Processing?如何在处理中使用矩阵旋转向量?
【发布时间】:2010-10-07 12:50:41
【问题描述】:

我正在尝试使用矩阵来旋转向量,但很困惑。

我认为我需要做的就是创建一个旋转矩阵并将其乘以一个向量以获得旋转后的向量。

Here你可以看到我使用Processing完成的一个简单测试:

使用 a 增加旋转,使用 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();
}

Processing 带有我用过的PVectorPMatrix3D

我没有使用应该使用的 PMatrix 还是这是一个错误? 有什么提示吗?

【问题讨论】:

    标签: 3d vector matrix geometry processing


    【解决方案1】:

    这是罪魁祸首:

    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;
    

    将解决问题。

    【讨论】:

      【解决方案2】:

      除了 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 都假定为弧度...

      希望有帮助!

      【讨论】:

      • 非常好!谢谢!我正在查看文档(dev.postspectacular.com/docs/core/toxi/geom/…),发现标题XY、XZ、YZ 非常方便。如果我有 4 个顶点和一个法线,如何获得 Z 轴上的旋转?如果我在法线上使用航向方法,Z 将始终相同,因为我正在处理 1 个顶点。有什么提示吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      相关资源
      最近更新 更多