我正在处理创建一些3D对象的处理,我创建了一个递归方法,我希望生成一个具有更多自由度的手指状对象。我们的想法是,每个细分显示为一个框,生成一个新细分,使其底面与前一个细分的底部位于同一位置(如下所示)。 < / p>
问题在于,当我尝试旋转多个轴(即将deltaX和deltaZ都设置为0.3)时,我的算法失败了,我得到一些奇怪的东西(如下所示)。
我使用了旋转矩阵,以便尝试计算新段的基础应该基于旧的基础,并且它仅适用于1个旋转轴但是在多个上失败(数学在if语句中)。我已经看过关于Quaternions的帖子,但我真的很好奇为什么我的矩阵数学不起作用,或者如果Quaternions真的好得多,我可以在我的代码中实现它们。提前谢谢!
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空间中移动的代码,以及设置/变量初始化] [编辑(2):MCVE更新,更改deltaX,deltaY,deltaZ以进行移动]
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);
}
}
答案 0 :(得分:2)
我不确定你绘制每个方框后 之后的旋转和翻译是什么。它们导致你的转换不是真正“堆叠”。我可以盯着他们看另一个小时来提出为什么他们导致了这种行为,但我对3D的东西并不擅长。
但是这样考虑一下:
在每次拨打tree()
时,您希望自己的来源位于您刚刚绘制的框的顶部(您要绘制的框的底部) ),你希望旋转“堆叠”。
如果你这样接近它,那么你只需要做一些事情 - 首先你要做你的旋转(因为原点已经在底部),然后你将转换到中心来画你的盒子,然后你将翻译到你的盒子的顶部,这是你想要下一个盒子底部的位置。可能更容易向您展示代码:
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);
}
}
该代码似乎做了你想做的事情 - 它更像是一条“蛇”,每个部分从上一部分结束开始。
顺便说一下,这是一个有趣的小玩具,我很想知道你最终用它做了什么!