Diskussion:Kollisionsbehandlung (ActionScript)

aus GlossarWiki, der Glossar-Datenbank der Fachhochschule Augsburg

Berechnung der Abprallgeschwindigkeit über das Skalarprodukt

dx = dx/len;
dy = dy/len;
a_sc = -avx * dx - avy * dy;
b_sc = bvx * dx - bvy * -dy;
a_cx = -dx * a_sc;
a_cy = -dy * a_sc;
b_cx = dx * b_sc;
b_cy = dy * b_sc;

Dabei muesste gelten:

a_sc = -avx * dx - avy * dy = -1 (avx * dx + avy * dy)
b_sc = bvx * dx - bvy * -dy = bvx * dx + bvy * dy

wobei bei a_sc das negative Vorzeichen sinnlos ist, wenn:

a_cx = -dx * a_sc

und analog mit y, denn:

a_cx = dx * -a_sc = dx * -[-1 * (avx * dx + avy * dy)]
=> a_cx = dx * (avx * dx + avy * dy)

Also "relativer Abstand mal Skalarprodukt des relativen Abstand- und Geschwindigkeitsvektors"

Also muesste sich das ganze dazu vereinfachen lassen:

dx = dx / len;
dy = dy / len;

a_sc = avx * dx + avy * dy;
b_sc = bvy * dy + bvy * dy;

a_cx = dx * a_sc
a_cy = dy * a_sc

b_cx = dx * b_sc
b_cy = dy * b_sc

Wenn ich mich nicht irre, muesste das laut der Herleitung funktionieren. Der Algorithmus funktionierte bei meinen Versuchen leider nicht, wobei ich sagen muss, dass ich das ganze in C++ gemacht habe und dort meine Vector-Klasse (http://blog.visusnet.de/2007/09/12/vektoren-fuer-c-programmierer/) benutze, wodurch der Quellcode ziemlich anders aussieht. Hier mal im Vergleich:

/*
 * Definitionen:
 * ObjectWrapper *objectA, *objectB;
 * Vector *positionA, *positionB;
 * Vector deltaPosition;
 * double scalarA, scalarB;
 */

// dx = dx/len;
// dy = dy/len;
deltaPosition = (*positionA - *positionB);
deltaPosition.Normalize();

// Vorzeichenkorrektur, wuerde auch mit abs(),
// also dem Betrag der Werte funktionieren.
if (deltaPosition.x < 0)
{
    deltaPosition.x *= -1;
}

if (deltaPosition.y < 0)
{
    deltaPosition.y *= -1;
}

// a_sc = -avx * dx - avy * dy;
// b_sc = bvx * dx - bvy * -dy;
// GetSpeed() liefert den Geschwindigkeitsvektor
scalarA = deltaPosition * objectA->GetSpeed();
scalarB = deltaPosition * objectB->GetSpeed();

// a_cx = -dx * a_sc;
// a_cy = -dy * a_sc;
// b_cx = dx * b_sc;
// b_cy = dy * b_sc;
Vector tempSpeedA = deltaPosition * scalarA;
Vector tempSpeedB = deltaPosition * scalarB;

// element2.vx = bvx - (b_cx - a_cx) * v_bouncing;
// element2.vy = bvy - (b_cy - a_cy) * v_bouncing;
// element1.vx = avx - (a_cx - b_cx) * v_bouncing;
// element1.vy = avy - (a_cy - b_cy) * v_bouncing;
int bouncing = 1;

objectA->SetXSpeed(objectA->GetXSpeed() - (tempSpeedB.x - tempSpeedA.x) * bouncing);
objectA->SetYSpeed(objectA->GetYSpeed() - (tempSpeedB.y - tempSpeedA.y) * bouncing);
objectB->SetXSpeed(objectB->GetXSpeed() - (tempSpeedA.x - tempSpeedB.x) * bouncing);
objectB->SetYSpeed(objectB->GetYSpeed() - (tempSpeedA.y - tempSpeedB.y) * bouncing);

Bei meinem C++-Quellcode schiessen die beiden Objekte wild durch den Raum, wenn sie aufeinander treffen, wobei ich feststellen konnte, dass der x Wert der Objekte abwechselnd positiv und negativ mit den selben Werten ist.

Vielleicht habe ich das ganze auch nur falsch portiert. ... Bin fuer Hinweise dankbar ;-)

-- Visus 23:40, 25. Sep. 2007 (CEST)