Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

marfi

Treue Seele

  • »marfi« ist der Autor dieses Themas

Beiträge: 100

Wohnort: Schwerte

  • Private Nachricht senden

1

17.10.2012, 21:47

2D Kollision von Bällen

Hallo Leute,

seit Ewigkeiten habe ich mal wieder etwas programmiert. Und gleich ein blödes Problem.
Ich habe 60 Bälle auf dem Schirm und lasse sie von den Wänden und von sich selbst abprallen. (negiere den Richtungsvektor)
Aber hin und wieder bleiben 2 Bälle aneinander hängen, wahrscheinlich ist der Stoßwinkel zu klein.

Das heißt der Richtungsvektor wird in jedem Frame hin und her getauscht, weil die Kollision noch anliegt.

Mein Dilemma, wie komme ich aus der Sache raus?

Hat jemand einen Tip?

2

17.10.2012, 21:51

Schau was passiert wenn es einen Schritt weiter geht. Heißt: Rechne nochmal einen Schritt weiter, wenn es dann negiert ist.
Sobald es beim selben Ball wieder negiert wird, schaust du wo sich der Ball befindet, oben links, unten links, oben rechts, unten rechts vom jeweils anderem Ball.
Dementsprechend kannst du dann den Ball herausschieben.
Wäre mein Ansatz.

MfG
Check

Durza

Treue Seele

Beiträge: 104

Beruf: Student (MSc Cyber Security)

  • Private Nachricht senden

3

18.10.2012, 00:22

Oder du machst es so, dass du für jeden Ball eine zufällig lange "Wartezeit" festlegst (bei Kollision), damit sich nicht alle zur selben Zeit "lösen" wollen.

Durza

4

18.10.2012, 01:10

Durza: Wie kann man eigentlich ein Student am Gymnasium sein? o.ö
Äh, egal.
Mag sein, dass ich da nicht ganz mitgekommen bin, aber fliegen sie dann nicht durch andere durch und können sie dann nicht trotzdem kurzzeitig stecken bleiben?
Naja, an sich käme es dabei natürlich auch drauf an, wie hoch er die Grenzen für die zufällige Zeit setzt. Trotzdem bleibt ja Problem 2.
Wenn man sich damit zufrieden geben will, dass sie nicht immer instant abprallen ist das sicherlich eine gute Lösung.

MfG
Check

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

5

18.10.2012, 07:01

Ist doch eigentlich einfach. Vor dem Stoß bewegen sie sich so auf einander zu, dass sich ihre Richtungen kreuzen. Das sollte nach dem Stoß unmöglich sein. Und da hast Du auch die Bedingung dafür, dass keine Kollision stattfinden darf. Ich weiß nicht, wie Du es momentan überhaupt gelöst hast, aber es klingt merkwürdig.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

CBenni::O

1x Contest-Sieger

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

6

18.10.2012, 16:03

Den Richtungsvektor negieren reicht leider nicht. Du musst die Komponente des Bewegunsvektors negieren, mit dem sie sich aufeinander zubewegen. Das berechnest du so (p1,p2 positionen, r1,r2 radien, v1,v2 bewegunsvektoren):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
// Vebindungsvektor (normiert):
vec2 d = normalize(p2-p1);
// orthogonalvektor dazu (x,y)->(-y,x)
vec2 o = (-d.y,d.x);

// Neue Geschwindigkeit für 1. Kugel:
v1 = v1*dot(v1,o)-v1*dot(v1,d);

// Neue Geschwindigkeit für 2. Kugel:
v2 = v2*dot(v2,o)-v2*dot(v2,d);

// Den Abstand der Kugeln anpassen (damit sie sich nicht mehr schneiden)
p2 = p1+d*(r1+r2);

(Ungetestet)

Bemerkung: 'tschuldigung, dass ich einfach ein komplettlösing hinhaue, aber jemand, der kein Buch über (2D-)Geometrie oder eine Vorlesung über Lineare Algebra gehört/gelesen hat, kommt nicht darauf.

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

7

18.10.2012, 17:13

Um das ganze ein wenig mehr zu Verstehen (und nicht nur den Code von Benni kopieren):
http://www.3dkingdoms.com/weekly/weekly.php?a=2

Das spezielle an Bällen ist, dass du zuerst die Normale berechnen musst (das was benni in Zeile 4 macht).

Wenn du das jetzt generell verstehst kannt du auch Abprallen an Wänden etc. elegant lösen.

CBenni::O

1x Contest-Sieger

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

8

19.10.2012, 16:43

Übrigens, du musst noch eine Änderung vornehmen: Bei der Kollision tauschen sich die Geschwindigkeiten!

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Vebindungsvektor (normiert):
vec2 d = normalize(p2-p1);
// orthogonalvektor dazu (x,y)->(-y,x)
vec2 o = (-d.y,d.x);

float speed1 = v1.DotProduct(d);
float speed2 = v2.DotProduct(d);

// Neue Richtung für 1. Kugel:
v1 = o*dot(v1,o)-normalize(d*dot(v1,d))*speed2;

// Neue Richtung für 2. Kugel:
v2 = o*dot(v2,o)-normalize(d*dot(v2,d))*speed1;

// Den Abstand der Kugeln anpassen (damit sie sich nicht mehr schneiden)
p2 = p1+d*(r1+r2);


Wieder ungetestet :D
Ich werde diesen Code selbst als referenz nehmen, fyi

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »CBenni::O« (26.10.2012, 17:51)


marfi

Treue Seele

  • »marfi« ist der Autor dieses Themas

Beiträge: 100

Wohnort: Schwerte

  • Private Nachricht senden

9

19.10.2012, 22:07

Vielen Dank für die Antworten und Tips.

@Benni: Dir Dank für die Lösung.

Ich hatte es jetzt erstmal so gelöst, das alle Bälle, die länger als 1 Frame kollidieren das Gegenteil vom Kollisionspartner machen.

Eigentlich war das Ganze dazu gedacht, eine Kollisionsfunktion zu testen. Aber die ist im Moment fast genauso langsam oder schnell wie die brute force Methode.

Ich gucke mir eure Tips mal genauer an und melde mich nochmal. :)

marfi

Treue Seele

  • »marfi« ist der Autor dieses Themas

Beiträge: 100

Wohnort: Schwerte

  • Private Nachricht senden

10

24.10.2012, 16:42

Also so ganz habe ich das mit den Vektoren noch nicht verstanden.

Vector2D vecPos = Position des Balls.
Vector2D vecVel = Geschwindigkeit und Verschiebung des Balls.

Also hat der Vektor vecVel seinen Ursprung in VecPos und sein Ende in vecPos + vecVel?

Nach dem Link „Reflecting a Vector“ müsste die Berechnung dann doch so aussehen. Wobei ich es in verschiedenen Varianten probiert habe und oft komische Ergebnisse bekomme. (Bälle weg, manche klumpen, ...) egal.

Hier mein Gedanke:

vecDiff = vecPos2-vecPos1

vecN = NormalenVektor(vecDiff)

beide normalisieren

vecVel1 = vecVel1 * (-2 * Dot(vecDiff, vecN)* vecN – vecDiff)

Mir erscheint es, als würde ich etwas nicht verstehen J Die Lösung von oben habe ich auch mal getestet, dabei verschwinden meine Bälle aber ganz schnell nach rechts unten. Die Velocity wird extrem groß.

Hat jemand von euch noch einen link über diese Thematik?

Das Skalarprodukt soll die Winkelberechnung ersetzen? Irgendwie muss man doch auch die verschiedenen Geschwindigkeiten berücksichtigen damit der Ball in die richtige Richtung gekickt wird.

So wie beim Billard.

Eigentlich wollte ich das nicht so genau programmieren, aber jetzt nervt es mich, das ich das nicht so richtig hinbekomme. Und den echten Durchblick habe ich auch noch nicht. ;)

Werbeanzeige