gpt4 book ai didi

c++ - 圆形碰撞反弹无法正常工作

转载 作者:搜寻专家 更新时间:2023-10-31 01:15:34 25 4
gpt4 key购买 nike

我正在用 C++ 编写一个小的物理模拟,基本上是在屏幕上移动圆圈,当两个圆圈碰撞时,它们应该以与台球相同的方式弹跳。当圆圈确实相互碰撞时,大多数时候它们实际上会无限减速/它们似乎彼此粘在一起并变成静止的。有时只有一个球会在碰撞中反弹,而另一个会保留其轨迹。这只是一个简单的二维模拟。

下面是我的检测/跳弹逻辑:

bool Ball::BallCollision(Ball &b2)
{
if (sqrt(pow(b2.x - x, 2) + pow(b2.y - y, 2)) <= b2.radius + radius) // Test for collision
{
normal[0] = (x - (x + b2.x) / 2) / radius; // Finds normal vector from point of collision to radius
normal[1] = (y - (y + b2.y) / 2) / radius;
xvel = xvel - 2 * (xvel * normal[0]) * normal[0]; // Sets the velocity vector to the reflection vector
yvel = yvel - 2 * (yvel * normal[1]) * normal[1];

////x = xprev; // These just move the circle back a 'frame' so the collision
////y = yprev; // detection doesn't detect collision more than once.
// Not sure if working?
}
}

我不知道我的函数有什么问题。提前感谢您的帮助!

编辑:每个变量都声明为 float

功能:

void Ball::Move()
{
xprev = x;
yprev = y;
x += xvel;
y += yvel;
}

void Ball::DrawCircle()
{
glColor3ub(100, 230, 150);
glBegin(GL_POLYGON);
for (int i = 0; i < 10; i++)
{
angle = i * (2*3.1415/10);
newx = x + r*cos(angle);
newy = y + r*sin(angle);
glVertex2f(newx, newy);
}
glEnd();
}

循环:

    run_prev.clear(); // A vector, cleared every loop, that holds the Ball objects that collided

for (int i = 0; i < num_balls; i++)
{
b[i].Move();
}

for (int i = 0; i < num_balls; i++)
{
b[i].WallCollision(); // Just wall collision detecting, that is working just fine
}

//The loop that checks for collisions... Am I executing this properly?
for (int i = 0; i < num_balls; i++)
{
for (int j = 0; j < num_balls; j++)
{
if (i == j) continue;
if (b[i].BallCollision(b[j]) == true)
{
run_prev.push_back(b[i]);
}
}
}

for (int i = 0; i < num_balls; i++)
{
b[i].DrawCircle();
}

//xprev and yprev are the x and y values of the frame before for each circle
for (int i = 0; i < run_prev.size(); i++)
{
run_prev[i].x = run_prev[i].xprev;
run_prev[i].y = run_prev[i].yprev;
}

最佳答案

  1. 使球发生碰撞(反射(reflect)运动 vector )仅当它们相互靠近时。如果它们彼此远离,则不要处理碰撞。打破这个规则,他们就会粘在一起。
  2. 处理碰撞时,同时更新两个球。不要一次更新一个球。
  3. 你的移动 vector 调整不正确。球不会相互反射,因为它们可以以不同的速度移动。

正确的运动调整(假设球具有相同的质量)应该看起来像这样:

pos1 and pos2 = positions;
v1 and v2 are movement vector (speed);
n is collision normal == normalize(pos1 - pos2);
collisionSpeed = dot((v2-v1), n);
collisionSpeed *= elasticy; (0.0..1.0);
v1 = v1 - dot(v1, n);
v2 = v2 - dot(v2, n);
v1 -= scale(n, collisionSpeed * 0.5);
v2 += scale(n, collisionSpeed * 0.5);

要了解公式,请查看牛顿定律(尤其是冲量定律)。或者查看 Chris Hecker 关于游戏物理的论文。

关于c++ - 圆形碰撞反弹无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9954049/

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