# 2 Bälle, die sich abstoßen



## Woggle (11. Sep 2010)

Huhu,
Ich arbeite gerade an einer Art Pong-klon. 
Ich habe dort 2 Bälle eingebaut. Nun möchte ich, dass wenn sich die Bälle treffen diese in einem zufällig erzeugten Winkel (zwischen -90 und 90 Grad) abstoßen. Zwischen -90 und 90 Grad deshalb, weil die Bälle ja sonst wieder aufeinander zufliegen.

Die Koordinaten der Bälle sind als double gespeichert, ebenso die Geschwindigkeit von diesen.

Es funktioniert auch alles soweit, bis jetzt hab ich einfach eingestellt, dass sich die Bälle einfach um 180 Grad drehen und voneinander entfernen (Also speedX = -speedX und speedY = -speedY). Dies funktioneirt ohne Probleme

Ein Zufälligen winkel zu erzeugen ist ebenfalls kein problem:

```
//Zufälliger Winkel zwischen -90 und 90 Grad erzeugen
Random random = new Random();
int winkel = random.nextInt(181) - 90;
```

Allerdings fehlt mir nun total der Ansatz. Wie berechne ich die neuen Werte für speedX und speedY?
Gegeben habe ich ja eigentlich nur den Winkel und die länge des neuen Vektors (Da sich alle Richtungen auf einem Halbkreis bewegen). Die Trigonometrie kann ich auch nicht anwenden, da mir der Rechte Winkel bzw. weitere werte fehlen.

Ich hoffe ich habe mein Problem verständlich geschildert ^^
Also entweder ich steh gerade total auf dem Schlauch oder ich denke einfach wieder zu kompliziert.
Vielen Dank für die Hilfe.

Gruß,
Woggle


----------



## Lucky Luc (11. Sep 2010)

Verstehe ich das richtig, dass sich die Bälle an jedem beliebigen Ort mit beliebigen Richtungen treffen können? In dem Fall müsstest du nämlich die "Kollisionsachse" als Bezugssystem nehmen. Dazu rechnest du einfach den Winkel dieses Vektors aus, und zwar mit Math.atan2(deltaX,deltaY). Zu dem Winkel kannst du dann deinen Zufallswinkel addieren, dann hast du den neuen Winkel im Verhältnis zur x-Achse(?) und kannst über Sinus und Kosinus die neuen Werte für speedX und speedY ausrechnen.

Warum sollen sich die Bälle eigentlich nicht gleich realistisch abstoßen? Ist, denke ich, auch nicht viel komplizierte, vor allem, wenn die Bälle die gleichen Massen haben.
Grob gesagt müsstest du dann den Geschwindigkeitsvektor in zwei Komponenten zerlegen, eine, die in die Richtung der Kollision geht, und eine tangentiale. Den tangentialen Teil der Geschwindigkeit kannst du beibehalten; dazu addierst du dann einen weiteren Vektor, den du über die Stoßgesetze berechnen kannst. Wie gesagt, im Falle gleicher Massen besonders einfach, da dann v1=-v2 und v2=-v1 gilt.

Hoffe mal, das hilft dir weiter,
Lukas


----------



## Woggle (11. Sep 2010)

Hi,
Danke schonmal für deine Tipps.

Ich lasse sie nicht realistisch abstoßen, um einen zusätzlichen Schwirigkeitsgrad einzubauen. Denn das ganze wird um einiges schwiriger, wenn man nicht weiß, wie die Bälle zu einem zurückkommen 

Allerdings funktioniert das ganze noch nicht so ganz. folgendes ist mein Code:

```
public void kollisionBall(){
		//zuerst um 180 Grad drehen
		speedX = -speedX;
		speedY = -speedY;
		
		System.out.println("------------------------------------------------------");
		System.out.println("Vorher X: "+ speedX);
		System.out.println("Vorher Y: "+ speedY);

                //zufälligen Winkel erzeugen
		Random random = new Random();
		int winkel = random.nextInt(181) - 90;
		
		System.out.println("Winkel: "+ winkel);

                 //Der gesamte Winkel
		double winkelGes = Math.atan2(speedX, speedY) + winkel;
		
		double speed = Math.sqrt(Math.pow(speedX, 2) + Math.pow(speedY, 2));

		speedX = speed * Math.sin(Math.toRadians(winkelGes));
		speedY = speed * Math.cos(Math.toRadians(winkelGes));

		System.out.println("Nachher X: "+ speedX);
		System.out.println("Nachher Y: "+ speedY);
	}
```

Zunächst ist mir aufgefallen, dass sich die Bälle manchmal "verhaken". d.h. sie hängen ineinander und kommen nichtmehr voneinander los. Deshalb hab ich die Variablen mal ausgeben lassen. Daran berkt man, dass es nicht stimmt und die Bälle teilweise trotzdem wieder aufeinander zufliegen...

Was hab ich denn falsch gemacht?

Vielen Dank!


----------



## Lucky Luc (12. Sep 2010)

Soweit ich das sehe, nimmst du die falsche Achse als Bezugssystem. Du drehst die Richtung des Balles um 180 Grad und lässt ihn dann noch mal um bis zu 90 Grad in beide Richtungen drehen. Das funktioniert so lange gut, wie die Geschwindigkeit etwa die gleiche Richtung wie der Zusammenprall selbst hat. Stell dir aber mal vor, die Bälle fliegen in einem 90°-Winkel aufeinander zu und treffen sich dann. Wenn du nun die Geschwindigkeiten umdrehst und 90° in die falsche Richtung hinzufügst, kann es passieren, dass die Bälle wieder im 90°-Winkel aufeinander zufliegen (s. Bild).

Stattdessen solltest du die "Kollisionsgerade" (gelb) als Bezugssystem nehmen. Ich nehme an, du hast zur Kollisionskontrolle irgendwo den x- und y-Abstand der beiden Bälle ausgerechnet. Diese beiden Werte (z. B. deltaX und deltaY) kannst du dann nehmen, um den Winkel dieser Gerade zur x-Achse zu berechnen (mit atan2). Wenn ein Ball in die entgegengesetzte Richtung wegfliegt, kannst du die Richtung bedenkenlos um 90° (oder zumindest fast 90°) in beide Richtungen ändern, ohne dass sich die Bälle erneut berühren. Du musst bloß aufpassen, dass die Gerade in die richtige Richtung "zeigt"; eventuell musst du 180° zu diesem Winkel hinzufügen.


----------



## Woggle (14. Sep 2010)

EDIT: Erstmal Danke für die Hilfe und für die Zeichnung!

Hmpf, ich hab es immernoch nicht hinbekommen :/
Die Bälle verhaken sich nach wie vor. Im Moment sieht mein Code so aus:


```
public void kollisionBall(double deltaX, double deltaY){		
		//um 180 Grad drehen
		speedX = -speedX;
		speedY = -speedY;
		
		//Winkel der Kollision zur X-Achse berechnen
		double winkelX = Math.toDegrees(Math.atan2(deltaY, deltaX));
		
		//zufaelligen Winkel bestimmen
		Random random = new Random();
		
		int winkelZufall = random.nextInt(181) - 90;
		
		//Gesamter Winkel
		double winkelGes = winkelZufall + winkelX;
		
		//die Vorherige Geschwindigkeit mit Hilfe des Satzes des Pythagoras
		double speed = Math.sqrt(Math.pow(speedX, 2) + Math.pow(speedY, 2));
		
		//Neue Geschwindigkeiten mit Hilfe der Trigonometrie
		speedX = speed * Math.cos(Math.toRadians(winkelGes));
		speedY = speed * Math.sin(Math.toRadians(winkelGes));
		
	}
```

Ich dreh diesen Ball also zuerst um 180 Grad. Der Funktion habe ich nun den Abstand der beiden Bälle übergeben (deltaX, deltaY) und berechne den WinkelX mit Hilfe von atan2, und lasse diesen auch Gleich in Grad umwandeln. Danach erzeuge ich einen zufälligen Winkel zwischen 90 und -90 Grad, den ich zum gerade errechneten WinkelX addiere, um den endgültigen Winkel zu erhalten. Zum Schluss berechne ich die neuen Geschwindigkeiten.

Nach nun langem probieren und aufzeichnen funktioniert es immernoch nicht. die Bälle verhaken sich immernoch manchmal...

Die Berechnung der neuen Geschwindigkeiten ist doch richtig oder? jedenfalls denke ich das, da sich die Geschwindigkeit ja nicht ändert ist "speed" immer gleich. daraus braucht man dann nurnoch die anderen zu berechnen :/

deltaX und deltaY lasse ich berechnen indem ich einfach die jeweiligen Koordinaten der Bälle voneinander abziehe.


----------



## Marco13 (14. Sep 2010)

Nur als eingestreuten Tipp (hab' den Code jetzt nicht nachvollzogen) : Vielleicht wäre es hilfreich, erstmal die _richtige_ Kollision zu programmieren - so dass sie auch funktioniert! Und danach erst das Ergebnis mit ein bißchen Zufall zu "verfälschen" (das ist nämlich immer leicht: Was falsch machen  ).

In jedem Fall ist so ein neu erstelltes Random-Objekt aber die debug-Hölle. Während der Entwicklung sollte man ein Random-Objekt wohl eher als
private static final Random random = new Random(0); // Wichtig: 0 übergeben!
erstellen, damit immer wieder die gleichen Werte kommen und man Fehler besser nachverfolgen kann. In diesem speziellen Fall könntest du auch einen festen Wert statt des Random-Wertes verwenden, um den Fehler aufzuspüren. (Und wie oben angedeutet: Dieser "feste Wert" könnte erstmal 0 sein  )


----------



## Kanitrino (15. Sep 2010)

Nur mal zur Inspiration findes Du hier Attrakor ein paar sich anziehende und abstoßende Bälle.


----------



## Marco13 (15. Sep 2010)

Die Abstoßung ist dabei aber nicht energieerhaltend?
(BTW: Schalte doch Antialiasing ein - dann sehen die Applets noch hübscher aus  )


----------



## Xynon (20. Okt 2010)

Für jeden den das nebenbei mal interessiert:

Das ist kein Pong-Klon sondern eine Aufgabe von dem diesjährigen Bundeswettbewerb für Informatik (Runde 1 Aufgabe 2)
und ich finde das nicht fair, diese in ein Forum zustellen und lösen zu lassen.

Hier ein link zu den Aufgaben:
Bundeswettbewerb Informatik: 1. Runde


----------



## HoaX (20. Okt 2010)

Xynon hat gesagt.:


> und ich finde das nicht fair, diese in ein Forum zustellen und lösen zu lassen.
> 
> Hier ein link zu den Aufgaben:
> Bundeswettbewerb Informatik: 1. Runde


Nicht nur unfair, sondern nach den Teilnameregeln sogar verboten!


----------



## Marco13 (20. Okt 2010)

F-A-I-R? Ach so, das, wovon Idealisten immer reden 

*schulternzuck* In der zweiten Runde fliegt er raus....


----------



## Xynon (20. Okt 2010)

Naja, wenn ich das richtig gelesen hatte ist Gruppen arbeit erlaubt, also wenn das hier ein "private" Forum wäre dann kein Problem, aber so gehts nicht.

@irgendein Moderator 
Könnte der Thread bitte gelöscht werden, bzw. einige der relevanten Posts?


----------



## thE_29 (20. Okt 2010)

Der einzige Code wurde vom TE gepostet die anderen gaben nur Tipps..

Das ist auch ein bruch gegen diese Regel?


----------



## Xynon (20. Okt 2010)

Man darf logischer weise keinen Code veröffentlichen, auch wenn es sein eigner ist können ja die anderen Teilnehmer diesen lesen.

btw ich bin auch ein teilnehmer, wie man vieleicht schon bemerkt hat.
Auch wenn ich eine andere Programmiersprache nutze, habe ich zurzeit auch das PRoblem mit dem "verhacken", deswegen bin ich hier zufällig drüber gestolpert.

Könnte seine Posts bis zum 16. Nov ausblenden 15 ist einsendeschluss.


----------



## thE_29 (20. Okt 2010)

Najo, darf man nach allg. Tipps fragen (dann blende ich den Code aus) oder solls allg. verschwinden?


----------



## Xynon (20. Okt 2010)

Wie ich darüber schon geschrieben habe: bis zum 16. November 2010 bitte den Quellcode verschwinden lassen.
Ich kenne leider nicht die Board möglichkeiten, ob nun ausblenden oder was auch immer, man sollte ihn bis dahin nur nicht mehr lesen können.


----------



## vladimir75 (20. Okt 2010)

Hehe, ich erinnere mich an meine Java-Prüfung in der FH, das war etwa Jahr 2004-2006. Es war damals 7 Stunden lange Prüfung. Man müsste anwesend sein, eine Aufgabe auswählen, jede mögliche Hilfe außer Internet benützen dürfen. Bücher, alte arbeiten, Programmen usw dürfte alles mit nehmen. In 7 Stunden sollte jeder eigenes Programm vorstellen. Die Professoren haben damals die Prüfung abgeändert, anstatt einem 3mon Projektarbeit eintägiger Arbeit vor dem Rechner. Wir haben selbstverständlich pausen gehabt, Mittagspause sind alle essen gegangen. Ich bin in ein anderes Gebäude, wo auch ein Computerraum war. Ratet ihr,  welche Adresse ich angegeben habe. Ja, klar Java programmieren aus Leidenschaft. Damals habt ihr mir bissel geholfen, finde aber diese Threads nicht mehr. 


Ich sehe nirgendwo ein Verbot diesen Code zu veröffentlichen. Kannst du einen Link zu den Teilnamenbedingungen hier posten.

Vladimir


----------



## A0027301 (20. Okt 2010)

"Ich sehe nirgendwo ein Verbot diesen Code zu veröffentlichen"

Veröffentlichen? Er hat ja nicht seinen Code veröffentlicht, sondern wollte die Lösung zu einem Problem. 
Nun kann man diskutieren, ob man Teilprobleme in einem Forum lösen lassen kann. Nunja Forum1 löst Teilproblem1, Forum2....

Stecke alles zusammen und gewinne den Preis
Empfinde das schon als Betrugsversuch.....


----------



## Marco13 (20. Okt 2010)

Vorausgesetzt, er wollte es auch abgeben und ... (hier eine Kette fadenscheiniger Argumentationen, Diskussionen und Grenzfallabtastungen einsetzen, die endet mit der Frage: ) ... ist die Standard-API-Doku schon eine "unerlaubte Hilfe"?

Spätestens bei den Präsenzaufgaben fliegt er raus. Man braucht ja nicht zu glauben, dass alle abgegebenen Beiträge 100% von den Einsendern selbst erstellt sind....


----------



## Apo (20. Okt 2010)

Stimme Marco vollkommen zu. 
Ich habe früher da auch mitgemacht und mich mit Freunden abgesprochen und die teilweise gefragt ... wäre das dann auch cheaten? Und er hatte wirklich seinen Code hier nicht veröffentlicht bzw. nur nach einem Teilproblem gefragt und sich Anregungen geholt. Aber wie erwähnt spätestens ab Runde 3 fällt die Möglichkeit des Internets/Forums weg.

Ich möchte aber gar nicht mitdiskutieren ... auch wenn ich schon eine Weile nicht mehr mitgemacht habe bzw. mitmachen darf ... danke für den Tipp und die Erinnerung. Ich habe gleich mal 3 Aufgaben optisch halbwegs ansprechend umgesetzt. Hatte ich schon wieder ganz vergessen, dass es den gibt. Freu mich schon auf die Aufgaben in Runde 2. =)


----------



## Tomate_Salat (20. Okt 2010)

und wenn er nun wirklcih an einem klon arbeitet^^

@Xyon: haste dich extra angemeldet um hier zu protestieren? Wie bist du denn auf diesen Thread gekommen? Du hast nicht rein zufällig nach einer Lösung gegoogelt?:rtfm::autsch:


----------



## Xynon (20. Okt 2010)

@thE_29, Marco13, vladimir75
Ja, meinetwegen lasst es drin stehen, weit ist er ja nicht gekommen.

@Apo
Gruppenarbeit ist ja auch ausdrücklich erlaubt, dann muss man sie auch als solches angeben und wenn er auch geschrieben hätte wofür er das macht wäre ich auch nicht so dagegen. Mir geht es hier um das erschleichen von Information, unter falschen Tatsachen. Ich empfinde so was als Betrug.

@Tomate_Salat
Muss ich alles doppelt schreiben ?
Ja, habe ich, ich bin hier wie schon gesagt drüber gestolpert wie ich im Post gegen 13Uhr geschrieben habe. Weil ich genau das selbe Problem habe das die sich verhaken, was mir logisch erscheint bei der Aufgabenstellung. Und jetzt wollte ich erstmal mich zur Kollision einlesen und habe halt Kollision zweier Bälle "gegooglet" und dann bin ich hier gelandet


----------



## Woggle (20. Okt 2010)

Um mich mal zu melden:

1. Selbst wenn das für den Wettbewerb wäre, würden diejenigen, die die Aufgaben Auswerten wohl auch diesen Post sehen können

2. Ist Teamarbeit in der ersten Runde ausdrücklich erlaubt und erwünscht. Quelle: Bundeswettbewerb Informatik: FAQ

3. Hab ich meinen eigenen Code gepostet, zu dem ich den Fehler gesucht habe und nicht die Lösung. So gesehen kann man also jeden Post zu irgendeinem Pong spiel als Lösung für diese Aufgabe nehmen

4. wurde mein Problem hier nicht gelöst, das heißt es gibt keinerlei Hilfe. Mit einem nicht funktionierenden Code kann man nichts anfangen.

5. Hast du nach einer Lösung gegooglet. Ist das besser?

6. Finde ich um einiges schlimmer Behauptungen aufzustellen und mich als Lügner ohne irgendwelches wissen darüber zu bezeichnen. Aber ich werde den Code löschen, dann kann der Thread geschlossen werden
EDIT: Kann die Posts nichtmehr verändern. Bitte ein Mod den Code rauslöschen, damit es keine Missverständnisse mehr gibt. Danke


----------



## Tomate_Salat (21. Okt 2010)

Xynon hat gesagt.:


> Und jetzt wollte ich erstmal mich zur Kollision einlesen und habe halt Kollision zweier Bälle "gegooglet" und dann bin ich hier gelandet



und was macht dich soviel besser, dass du über ihn und sein Post urteilen darfst? Zumal du nicht mal sicher sein kannst, dass er nicht wirklich versucht einen Pong-klon zu basteln ohne am Wettbewerb teil zu nehmen.

Außerdem: wie zur hölle kommst du darauf, dass ihm ijemand hier die Kollision schreiben würde? Er bekommt Hilfe zur Umsetzung und nicht mehr.


----------



## Marco13 (21. Okt 2010)

Ein Pong-Klong kann es wegen der SEHR spezifischen Fragestelltung eigentlich kaum sein. Und selbst wenn jemand die Komplettlösung (am besten noch als [c]public class BWISolution2[/c] posten würde, wäre das egal. Sowas ist da mit einkalkuliert. :bahnhof:


----------

