Ich schreibe ein wenig Physik-Simulation in C++, die grundsätzlich Kreise über den Bildschirm bewegt und wenn zwei Kreise kollidieren, sollten sie in der gleichen Weise abprallen wie Billardkugeln. Wenn die Kreise miteinander kollidieren, werden sie die meiste Zeit praktisch unendlich verlangsamen/sie scheinen aneinander zu haften und werden statisch. Manchmal prallt nur ein Ball bei der Kollision zurück und der andere behält seine Flugbahn bei. Dies ist nur eine einfache 2D-Simulation.Circular collision rebound funktioniert nicht richtig
Also hier ist, was ich für die Erkennung/Ricochet Logik:
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?
}
}
ich nicht herausfinden kann, was mit meiner Funktion falsch ist. Danke für jede Hilfe im Voraus!
bearbeiten:
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();
}
Die Schleife:
das normal ist falschrun_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;
}
Sie sollten angeben, welche Typen Ihre Variablen sind, nur um zu wissen, ob wir Rundungsfehler oder andere Casting-Fehler ausschließen können. – vsz
Ich verstehe nicht, warum Sie so normal berechnen. Sollen sie Einheitslänge haben? –
Ich dachte, sie wären. Bitte korrigieren Sie mich, wo auch immer ich hingefallen bin. – Christian