我在使用 JOGL 计算我想要的运动时遇到了问题。书上的例子莫名其妙用到了System.timeInMillis()
的sin()
和cos()
。
stack.translate(Math.sin(amt)*4.0f, Math.sin(amt) * 1.0f, Math.cos(amt)*2.0f);
这一切都很好,问题是我想知道他们从哪里得到这些数字,以及如何计算平滑下落的立方体等等。
int pos = 1;
stack.translate(0.0, --pos, 0.0);
可以解决问题,但它是有限的。是否有任何资源指导如何使用这些神秘的 sin()
和 cos()
函数以非常具体的方式控制运动?
我正在调查相关问题。我需要的只是某种引用,我什至不知道这种东西应该叫什么来研究;流体动力学? 3D三角图形运动? 3D牛顿物理学?
最佳答案
这个方程并不神秘......它只是一个椭圆(扭曲的圆)的参数方程......让我通过它的推导来解释:
2D xy 平面圆:
x=x0+r*cos(t) y=y0+r*sin(t)
哪里
(x0,y0)
是圆心,r
是圆半径,t=<0.0,2.0*Pi>
是角度参数,确定您想要圆的哪个点。2D xy平面轴对齐椭圆
x=x0+rx*cos(t) y=y0+ry*sin(t)
我们只是在每个轴上使用了不同的半径。所以
rx,ry
也是半轴。3D 椭圆
如果我们将#2 椭圆旋转到3D,我们可以得到任何椭圆。为了使这变得简单,我们可以只沿着一个轴旋转,它将一个椭圆坐标分成两个......所以如果我重写你的等式:
x=sin(t)*4 y=sin(t) z=cos(t)*2
表示
z
是椭圆的起始轴(角度0
前轴x
)和x,y
轴是前者的旋转部分y
轴。椭圆以(0,0,0)
为中心并且有半轴2.0
和sqrt(1^2+4^2)
.
现在如果我们改变 t
然后将系统时间缩放到一定速度
t = amt = 2.0*Pi*system_time/T
在哪里T
是你的运动期。
现在,当您使用绝对平移时,您会将对象移动到沿椭圆的位置。如果您使用相对平移,则速度将由该椭圆驱动,从而导致更复杂的轨迹。如果你想要真正的物理使用,这只是假运动模拟 Newton D'Alembert physics并通过改变加速度来驱动你的物体。
如果你想制作人类驱动的对象,请查看此处的最后一个链接:
行星运动见:
因此,要回答您的第二个问题,请使用 Newton D'Alembert 和矢量数学。我假设 3D。所以让你的立方体有位置速度和加速度。
// init do this just once
pos=(0,0,0); // [m] start position
vel=(0,0,0); // [m/s] start velocity
acc=(0,-9.81,0); // [m/s^2] acceleration on object (gravity in -y direction)
// on some timer or before render ...
vel+=acc*dt;
pos+=vel*dt;
cube.translate(pos); // absolute translation of your cube
哪里dt [s]
是从上次计算开始耗时,所以在计时器的情况下,它是以秒为单位的时间间隔。您可以使用任何单位,但所有单位必须兼容 pos,vel,acc
.
您可以添加摩擦,例如:
acc+=k*vel*|vel|; // acc += k*vel^2
哪里k
是空气中的摩擦系数(在液体中为 k*vel^3
)远小于 1.0
.
要驱动您的物体,您可以使用驱动力...
acc += F/m;
哪里F
是驱动力和 m
的总和是你的物体的质量。
所有这些也可以针对角度(方向)完成,因为它有相似之处
alpha -> pos
omega -> vel
epsilon -> acc
并通过 alpha
使用对象的绝对旋转.
关于algorithm - 如何在 openGL 中计算运动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46107113/