gpt4 book ai didi

java - 矩形棱柱的 3D 旋转

转载 作者:行者123 更新时间:2023-11-30 03:06:24 27 4
gpt4 key购买 nike

我正在处理创建一些 3D 对象的过程,我创建了一个递归方法,希望能生成具有更多自由度的手指状对象。这个想法是,显示为框的每个段都会生成一个新段,使其底面与前一个段的底部位于同一位置(如下所示)。 Segment Finger

问题是,当我尝试旋转多个轴(即将 deltaX 和 deltaZ 设置为 0.3)时,我的算法失败,并且出现一些奇怪的情况(如下所示)。 Broken Segment Finger

我使用旋转矩阵来尝试计算新段的基础应该基于旧段的位置,它仅适用于 1 个旋转轴,但在多个旋转轴上失败(数学在 if 语句中)。我看过有关四元数的帖子,但我真的很好奇为什么我的矩阵数学不起作用,或者四元数是否真的更好,我如何在代码中实现它们。提前致谢!

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);
}
}

最佳答案

我不太确定绘制每个框之后的旋转和平移正在做什么。它们导致你的转换没有真正“叠加”。我可以再盯着它们看一个小时来想出为什么它们会导致这种行为,但我不擅长 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);
}
}

该代码似乎可以实现您想要的功能 - 它的行为更像是一条“蛇”,每个部分都从上一部分结束的位置开始。

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

关于java - 矩形棱柱的 3D 旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34670083/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com