首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >矩形棱镜的三维旋转

矩形棱镜的三维旋转
EN

Stack Overflow用户
提问于 2016-01-08 05:27:07
回答 1查看 660关注 0票数 1

我正在处理创建3D对象的过程,我创建了一个递归方法,我希望能够生成一个更多自由度的类似手指的对象。其思想是,每个段,显示为一个框,产生一个新的段,使它的底面是在同一位置上的前一段的底部(如下图所示)。

问题是,当我试图旋转多个轴(即将deltaX和deltaZ设置为0.3)时,我的算法失败了,我得到了一些奇怪的东西(如下所示)。

我使用旋转矩阵来尝试计算新段的基座应该以旧段为基础,它只对一个旋转轴工作,但在多个轴上失败(数学在if语句中)。我看过关于四元数的帖子,但我很好奇为什么我的矩阵数学不起作用,或者四元数在代码中的实现方式真的好得多。提前感谢!

代码语言:javascript
复制
void finger(float x, float y, float z, float rx, float ry, float rz, float r, 
float h){
  translate(x,-y,z);
  rotateX(rx);
  rotateY(ry);
  rotateZ(rz);
  translate(0,-h/2,0);
  box(r,h,r);
  translate(0,h/2,0);
  rotateZ(-rz);
  rotateY(-ry);
  rotateX(-rx);
  translate(-x,y,-z);
  if(r>10){
    finger(x+h*sin(rx)*sin(ry)*cos(rz)+h*cos(rx)*sin(rz),y-h*sin(rx)*sin(ry)*sin(rz)+  
    h*cos(rx)*cos(rz),z-h*sin(rx)*cos(ry),rx+deltaX,ry+deltaY,rz+deltaZ,r-4,h-5);
  }
}

编辑:下面的MCVE,包括我在3D空间中移动的代码,以及设置/变量初始化。

代码语言:javascript
复制
float deltaX,deltaY,deltaZ;
void setup(){
  deltaX=0;
  deltaY=0;
  deltaZ=0;
  fullScreen(P3D);
}
void draw(){
  noStroke();
  camera(-600, -400, -600, 0, -300, 0, 0, 1, 0);
  background(#51B6F5);
  directionalLight(255,255,255,0.5,1,0.5);
  directionalLight(255,255,255,-0.5,1,-0.5);
  box(400,10,400);
  tree(0,0,0,0,0,0,40,100);
}
void tree(float x, float y, float z, float rx, float ry, float rz, float r, float h){
  translate(x,-y,z);
  rotateX(rx);
  rotateY(ry);
  rotateZ(rz);
  translate(0,-h/2,0);
  box(r,h,r);
  translate(0,h/2,0);
  rotateZ(-rz);
  rotateY(-ry);
  rotateX(-rx);
  translate(-x,y,-z);
  if(r>10){
    tree(x+h*sin(rx)*sin(ry)*cos(rz)+h*cos(rx)*sin(rz),y-h*sin(rx)*sin(ry)*sin(rz)+h*cos(rx)*cos(rz),z-h*sin(rx)*cos(ry),rx+deltaX,ry+deltaY,rz+deltaZ,r-4,h-5);
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-08 21:04:46

我不太清楚,在绘制每个框的之后,正在做什么旋转和翻译。它们导致您的转换不是真正的“堆栈”。我可以再盯着他们一个小时,想出为什么会导致这种行为,但我并不擅长3D技术。

但要这样想:

在每次对tree()的调用结束时,您希望您的源位于您刚刚绘制的框的顶部(即将绘制的框的底部),并且希望这些旋转“堆栈”。

如果你这样做的话,你只需要做几件事情--首先你要做你的旋转(因为原点已经在底部),然后你会转换到中央来画你的盒子,然后你会翻译到你的盒子的顶部,这就是你想要下一个盒子底部的地方。只要向您展示代码,可能会更容易:

代码语言:javascript
复制
void tree2(float x, float y, float z, float rx, float ry, float rz, float r, float h){

  //assume current origin is at bottom of box

  //rotate around bottom
  rotateX(rx);
  rotateY(ry);
  rotateZ(rz);

  //move to center
  translate(0,-h/2,0);

  //draw the box
  box(r,h,r);

  //move origin to the top of the box- the bottom of the next box
  translate(0,-h/2,0);

  //draw the next box
  if(r>10){
    tree2(x+h*sin(rx)*sin(ry)*cos(rz)+h*cos(rx)*sin(rz),y-h*sin(rx)*sin(ry)*sin(rz)+h*cos(rx)*cos(rz),z-h*sin(rx)*cos(ry),rx+deltaX,ry+deltaY,rz+deltaZ,r-4,h-5);
  }
}

这段代码似乎可以做你想做的事情--它的行为更像是一条“蛇”,每一节都从上一节的结尾开始。

顺便说一句,这是一个有趣的小玩具,我会好奇,看看你用它做了什么!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34670083

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档