Man kann auch die einzelnen Linien testen. Du nimmst den Mittelpunkt des Balles und prüfst, ob der minimale Abstand zu den Linien jeweils kleiner oder gleich dem Radius ist.
Um den Abstand Punkt-Linie zu berechnen (Als Vektor), sollte der folgende (Pseudo-)Code helfen:
|
Quellcode
|
1
2
3
4
5
6
7
8
9
|
Vector2 PointLineDist(Vector2 point, Vector2 linestart, Vector2 lineend)
{
Vector2 a = lineend - linestart;
Vector2 b = point - linestart;
double t = dot(a, b)/(length(a)²);
if (t < 0) t = 0;
if (t > 1) t = 1;
return linestart + a * t;
}
|
Funktioniert auch bei Linien, die nicht entlang einer Koordinatenachse sind. Sie gibt den Punkt auf der Linie zurück, der dem Punkt am nächsten liegt.
Damit kannst du bestimmen, ob und wenn ja, wo der Ball auf eine Kante des Rechtecks trifft. Um den Ball korrekt abprallen zu lassen, lässt du ihn entlang dem verbindungsvektor zwischen dem mittelpunkt und der funktionwert nach dem einfallswinkel=ausfallswinkel-Gesetz abprallen. Dabei solltest du beachten, dass du dafür immer denjenigen Verbindungsvektor verwendest, der die minimale Länge hat. Damit kollidiert der Ball auch korrekt, wenn er auf eine Ecke zufliegt ;)
Ich hoffe, das hilft dir ein wenig, evtl werde ich noch etwas dazu posten, wie das abprallen am besten funktioniert.
EDIT: war einfacher, als ich dachte. Man teilt den geschwindigkeitsvektor auf, in einen vektor entlang der normalen, einen entlang der orthogonalen dazu, und zieht den ersten teil vom zweiten ab. Funktioniert wunderbar (erklärung dazu siehe Lineare Algebra):
|
Quellcode
|
1
2
3
4
5
6
7
|
// minvec = Kürzester Verbindungsvektor zum rechteck
// speed = geschwindigkeit des balles
Vector2 norm = normalize(minvec); // Normale
Vector2 orth = Vector2(norm.y,-norm.x); // Orthogonale
Vector2 snorm = dot(norm,speed) * norm; // Geschwindigkeitskomponente in normalen-richtung
Vector2 sorth = dot(orth,speed) * orth; // Geschwindigkeitskomponente in orthogonalen-richtung
speed = sorth - snorm; // neue Geschwindigkeit
|
mfg CBenni::O