【发布时间】:2017-01-18 11:19:33
【问题描述】:
我在对物体实施重力时遇到问题。
我有一堆使用 OpenGL 绘制的圆形对象。我正在使用delta-x 和delta-y 来移动圆圈(球)。我正在尝试在每个帧的y 坐标中添加一个引力常数,以便模拟被拉下,但我不确定该怎么做。
以下是相关代码:
class Ball
{
public:
double x;
double y;
double radius;
double deltaX;
double deltaY;
};
std::vector<Ball> gAllBalls; // a vector of balls with random positions and delta-values
double gGravity = ?; // gravitational constant - I know it's 92 m/s^s, but I don't know how to apply that to deltaX and deltaY
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
for (auto &thisBall : gAllBalls)
{
// draw
glColor3d(thisBall.red, thisBall.green, thisBall.blue);
DrawCircle(thisBall.x, thisBall.y, thisBall.radius);
// gravity - not working
if (thisBall.y + thisBall.radius < gScreenHeight - gGravity)
{
thisBall.y += gGravity;
}
// wall bouncing
if (thisBall.y + thisBall.radius + thisBall.deltaY >= gScreenHeight) // up
{
thisBall.deltaY = -thisBall.deltaY;
}
if (thisBall.y + thisBall.deltaY - thisBall.radius < 0) // down
{
thisBall.deltaY = -thisBall.deltaY;
}
if (thisBall.x + thisBall.deltaX - thisBall.radius < 0) // left
{
thisBall.deltaX = -thisBall.deltaX;
}
if (thisBall.x + thisBall.radius + thisBall.deltaX >= gScreenWidth) // right
{
thisBall.deltaX = -thisBall.deltaX;
}
// move
thisBall.x += thisBall.deltaX;
thisBall.y += thisBall.deltaY;
}
glutSwapBuffers();
glutPostRedisplay();
}
我遇到的一个大问题是我不知道如何计算重力,因为我使用 deltaX 和 deltaY 而不是使用单独的速度和距离变量来计算 92 m/s^ 2.但是,无论我将重力设置为什么,球的行为都不会像应有的那样 - 无论重力强度如何,所以肯定有其他问题,但我不知道是什么。
【问题讨论】:
-
thisBall.y += gGravity;这将导致恒定的速度,而不是恒定的加速度。如果你调整 deltaY 而不是 Y,你可能会更接近你想要的。最好使用工程单位,例如米和秒,而不是像素和任意时间步长,然后根据需要在它们之间进行转换。最后,你的“G”值是关闭的,它真的是 9.8 m/sec^2 -
啊,这当然更有意义。我将其更改为 deltaY 而不是 Y,它最初似乎可以工作,但是球开始越来越快地加速而不是减速。我只是使用 1 作为重力常数。我很想使用更好的单位,但我不确定如何实现它们。您有什么建议或资源吗?
-
"92 m/s^2",你在哪里模拟,某种超木星还是小恒星?
-
这是什么应用程序?如果你想模拟均匀引力场中的真实运动,你可以使用方程 y_{t} = y_{t-dt} + v_{y,t-dt}dt - 0.5gdt^{2}。 y_{t} 是时间 t 的位置,dt 是调用
display()之间的时间,v_{y,t-dt} 是上一个时间步的速度(上次调用display()),g是地球上重力加速度 (9.8m/s^{2}) 的大小。 -
@Grav 顺便说一句,没有真正的理由使用 9.8 m/s^2,除非您尝试对地球上的运动进行逼真的模拟。我在上面发布的方程式仍然会为您提供正确的运动类型,您可以将 g 更改为您认为看起来不错的任何值。