Kollision eines Kreises mit einem 270° Winkel im 2D-Raum

Java-Jr.

Mitglied
Hallo,
Falls das hier nicht ganz genau im richtigen Bereich ist, tuts mir leid, aber ich denke eigentlich, dass das bei den Anfängerthemen schon ganz gut reinpasst.....

Also, ich wollte nur mal so um mein LWJGL mal ein bischen anzuwenden ein kleines Pong schreiben und da ist mir das Problem mit der Kollision gekommen. Die Kollisionserkennung ist ja eher einfach, schwieriger ist, bei einer Kollision des (runden) Balles und einer Ecke eines Rechteckes darauf zu reagieren.....
Ich habe da diverse Sachen probiert und es sieht einfach immer unrealistisch aus, und ich hättte schon ganz gerne eine annähernde physikalische Genauigkeit, zumindest genau genug, damit man die Fehler mit dem Auge nicht erkennt ;).

Also, die Ecke des Schlägers hat eine X-und eine Y-Koordinate, der Ball hat im Mittelpunkt auch eine und natürlich einen Radius und eine Geschwindigkeit, die in Form eines Vektors, also so zum Beispiel [-2,5] angegeben und in jedem Frame zu seiner Position addiert wird (also eigentlich ganz normal).

Ich würde mich sehr über Lösungsansätze freuen, besonders, wenn sie nicht allzuschwer umzusetzen sind, meine momentane Idee (noch nicht implementiert) ist, grob gesagt, mit ganz komplexen Vektorrechnungen auf einen genauen Winkel zu kommen. Das lässt sich unschön implementieren und hat auch keinen physik-Hintergrund, kann also sehr leicht falsch werden.....

Also, danke schonmal :D
 

Marco13

Top Contributor
Die Kollisionserkennung ist ja eher einfach, schwieriger ist, bei einer Kollision [...] darauf zu reagieren.....

Dem ersten Teil würde ich nicht zustimmen, außer wenn er direkt in Relation zum zweiten gesetzt wird ;)

Für eine "gute" Kollisionsantwort ist aber auch die Frage relevant, WAS genau man bei der Kollisionserkennung erkennt. Was erkennst du? Dass sich der Ball und der Schläger am Ende des Zeitschrittes überschneiden werden? Das wird ein bißchen knapp (und kann natürlich bei schnellen Bewegungen schlicht dazu führen, dass der Ball durch den Schläger fliegt). Oder machst du irgendwas kontinuierliches? Das wäre dann der Fall, wo der erste Teil der obigen Aussage schon nicht mehr stimmen würde...

Dann wäre noch relevant, was alles modelliert werden soll. Soll der Ball nur abprallen? Ich nehme an, dass sowohl Ball als auch Schläger eine Position und eine Geschwindigkeit haben. Soll die Bewegung des Schlägers die Geschwindigkeit des Balls beeinflussen? Mit Massen, Impuls und allem drum und dran? Soll man dem Ball einen Drall geben können? Und wenn ja, wie hoch ist die Reibung zwischen Ball und Schläger? Du siehst, man kann beliebig weit gehen...

Eine Möglichkeit, die man in Worten recht leicht runterschreibt (und die für eine vollkommen elastische Kollision auch physikalisch nicht abwegig ist) aber deren Implementierung man schon nicht mehr aus dem Ärmel schüttelt:
- Man berechnet für den anstehenden Zeitschritt den Zeitpunkt t, an dem sich Ball und Schläger berühren
- Man berechnet für diesen Zeitpunkt t die Punkte pB=pS, an denen sich die Objekte berühren
- Man berechnet die Tangentialebene, an der der Ball abprallt (zum Glück ist ein Ball rund, und in diesem Fall ist es nur ein Kreis, d.h. man braucht nur die Linie, die senkrecht auf der Differenz zwischen pB und dem Kreismittelpunkt liegt - ansonsten bräuchte man die Ebene, die senkrecht zu pB-pS steht, was wegen pB=pS etwas tricky ist...).
- Änderung der Geschwindigkeit gemäß Einfallswinkel=Ausfallswinkel
- Zwischen t und dem Ende des Zeitschrittes bewegt sich der Ball mit der neuen Geschwindigkeit weiter (von seiner Position zum Zeitpunkt t aus) - und natürlich so lange, bis keine weitere Kollision auftritt.

Da die das 1972 aber vermutlich nicht so aufwändig gemacht haben, gibt es sicher eine vieeeel einfachere Möglichkeit, die die überzeugenden Ergebnisse liefert, die damals die Leute dazu veranlasst hat, für Pong Münzen in Spielhallenautomaten zu werfen.
 

Java-Jr.

Mitglied
Danke erstma, super Antwort, ich hab wohl echt noch etwas zu wenig gesagt, der Ball soll wirklich wie im Original einfach nur abprallen, ohne Geschwindigkeitsverlust, Spin, Reibung......
Meine Kollisionserkennung ist einfach gehalten: bei einer Überlappung gehts los. Auch hier hab ich sehr gerne Tipps, ich weiß selber, dass das nicht genau oder so ist, nur eben einfach. Würdest du den Speed der Komponenten und den Rest, der Zeitlich bedingt ist über die Systemzeit managen? Ist mir nur grade so eingefallen, das wäre Frameraten-Unabhängig und genau.....
Ja, der Schläger hat auch ein Geschwindigkeit, ich denke aber, dass ich das auch selbst hinbekommen hätte, die zu berücksichtigen, wenn der Rest läuft.

Also, bitte mehr Tipps ;)

MfG, Theo
 
Zuletzt bearbeitet:

DrZoidberg

Top Contributor
Also, wenn es ganz einfach sein soll, so wir im original Spiel, dann brauchst du keine komplizierten Berechnungen.
Die Schläger sind genau senkrecht also der Ball kollidiert, wenn ball.x - ball.radius < linkerSchläger.x oder halt ball.x + ball.radius > rechterSchläger.x.
Die y Komponente der Ballgeschwindigkeit ändert sich bei der Kollision nicht, nur die x Komponente wird negiert. Es sei denn die Geschwindigkeit des Schlägers beeinflusst den Ball. In dem Fall machst du einfach ball.speed.y += schläger.speed.y*faktor. ball.speed.x wird weiterhin einfach nur negiert. Der Ball kann nicht durch den Schläger durch fliegen, da die Bedingung ja lautet (ball.x - ball.radius < linkerSchläger.x). Da ist es egal wie schnell der ist, der kann nicht durchfliegen. Er kann den Schläger überlappen, aber das kannst du einfach ignorieren, da das bei ausreichend hoher Framerate gar nicht auffällt, wenn der Ball den Schläger für eine 60stel Sekunde überlappt.
 

Java-Jr.

Mitglied
Das ist nich ganz korrekt und auch nicht die Antwort auf meine Frage ;)

1. Ich habe (wie es im Titel steht) die Kollision des Kreises mit einer Ecke des Rechtecks gemeint, nicht mit einer Seite, wie das funktioniert glaube ich schon zu wissen.

2.Der Ball kann den Schläger sehr wohl durchfliegen, nur wie du sagst bei ausreichend hoher Frame-Rate nicht, bei einem Frame-Einbruch kann es durchaus dabei zu Fehlern durch diese "Durchfliegen" kommen, deshalb würde ich auch gern wissen, wie man eine Kollision genau und etwas im Vorraus erkennt.
 

Marco13

Top Contributor
Nun, DrZoidberg hat schon recht: Im Original wurde vermutlich lediglich die Koordinate geprüft, und um die Form der Ecke (und des Balls, abgesehen vom Radius) hat man sich nicht geschert. Der Ball kann dann zwar durch den Schläger fliegen, aber nur EINEN (ggf. sogar "unsichtbaren") Schritt lang, d.h. das ist egal. Und Ecken gibt es nicht. Entweder der Ball prallt ab, oder eben nicht. Vermutlich könnte man damit, wie angedeutet, das ganze SEHR viel einfacher machen, als wenn man versucht, dort irgendwas physikalisches zu machen und die Ecken zu berücksichtigen. (Ich persönlich finde aber, das einzige was so ein Spiel (oder sowas wie Breakout) interessant machen kann, ist, wenn das Abprallverhalten an den Ecken zumindest "anders" ist - es muss ja nicht "echte berechnet" sein...)
 

Crian

Top Contributor
Du möchtest erkennen, ob ein Punkt in Inneren (inkl. Kreisrand) eines Kreises liegt?

Ich habe das in einer Anwendung in meiner Kreisklasse so gelöst:

Java:
    /**
     * Ermittelt, ob der übergebene Punkt auf der Kreislinie oder innerhalb
     * davon liegt.
     *
     * @param point
     *            Zu überprüfender Punkt.
     * @return Wahrheitswert.
     */
    public boolean incloses(Point point) {
        double pointX = point.getX();
        double pointY = point.getY();

        double centerX = center.getX();
        double centerY = center.getY();

        /*
         * Falls der Klick außerhalb des umschließenden Quadrats ist, gleich
         * abbrechen:
         */
        if (pointX < centerX-radius || pointX > centerX+radius
                || pointY < centerY-radius || pointY > centerY+radius) {
            return false;
        }

        /* Nach Pythagoras: */
        double dx = pointX - centerX; // Vorzeichen egal, da quadriert wird
        double dy = pointY - centerY; // Vorzeichen egal, da quadriert wird
        if (dx*dx + dy*dy <= radius*radius) {
            return true;
        }
        else {
            return false;
        }
    }

Vielleicht hilft es ja.
 

Java-Jr.

Mitglied
Also, danke erstmal :)

Marco, ich hab das aber wie im NinjaCave (LWJGL Basics 4 (Timing) | NinjaCave) Tutorial gezeigt schon größtenteils Frame-Unabhängig gemacht, d.h. bei kleineren Frames steigt die geschwindigkeit und bei einem FPS kann das schonmal das halbe Spielfeld pro Frame sein, deshalb kann man auch den Schläger durchfliegen :(
Mir geht es hier wirklich darum, herauszubekommen, in welche Richtung der Ball von der Ecke des Schlägers zurückprallt, ich könnte wetten, dass man dazu den Sinus oder Kosinus verwenden sollte......??
Und hast du BITTE eine Idee oder einen Ansatz wie man das
das Abprallverhalten an den Ecken zumindest "anders" ist - es muss ja nicht "echte berechnet" sein...)
hinbekommt?


Crian, danke, das hab ich schon so ähnlich gelöst (genauso Pythagoras ;)):

Java:
            public static float AbstandVon(float[] ballKoordinate, float[] padderKoordinate) {
		float xAbstand = Math.abs(ballKoordinate[0] - padderKoordinate[0]);
		float yAbstand = Math.abs(ballKoordinate[1] - padderKoordinate[1]);
		return (float) Math.pow(Math.pow(xAbstand, 2) + Math.pow(yAbstand, 2), 0.5);
	}

Wenn dieser Abstand kleiner als der Radius des Kreises ist, etc....
 

Marco13

Top Contributor
Zum letzten Codestück: Mach' es so wie Crian es geschrieben hat. (Das abs ist überflüssig, das pow ist langsamer als x*x, und wenn man wirklich den Abstand braucht (und nicht wie in Crians Beispiel der quadrierte Abstrand ausreicht) sollte man sqrt statt pow(...,0.5) verwenden)

Zum Rest:... Nunja... sollte man wirklich von dem Fall von 1 FPS ausgehen? Also, wenn das eintritt (z.B. weil man einen schreicklich suboptimalen Pythagoras implementiert hat ;)) ist das Spiel ohnehin unspielbar. Wenn Der Ball beim 1. Frame in der Mitte des Bildschirms wäre (und sich nach links bewegt) und beim 2. Frame wieder in der Mitte ist (sich aber nach rechts bewegt, weil er links abgeprallt ist) wäre das irritierend...

Das Abprallverhalten an den Ecken: Ich meinte, dass man sich bestimmt was einfaches überlegen kann. Z.B. dass man die Schläger wie ein
Code:
  __
 /  \
 |  |
 |  |
 |  |
 |  |
 \__/
modelliert (auch wenn man ihn dann ggf. anders, d.h. mit richtigen Ecken an den Ecken) zeichnen könnnte!). Wenn der Ball an den senkrechten Stellen | aufprallt, wird er ganz normal zurückgeworfen:
movementX = -movementX.
Wenn er an der oberen oder unteren Schäge / \ auftrifft, macht man sowas wie
movementX = -movementX / 2;
movementY = movementY + movementX / 2; // bzw
movementY = movementY - movementX / 2; //
je nachdem ob es oben oder unten an der Ecke war (ist nur ein Gedanke, der das ganze VIEL einfacher machen würde, als eine "echte" Berechnung, aber wie sich das dann spielen läßt, ist schwer zu sagen. (Insbesondere müßte man irgendwas machen, um zu verhindern, dass movementX bei jedem Eckentreffer immer kleiner wird...)
 

DrZoidberg

Top Contributor
Also der Schläger besteht praktisch aus mehreren Teilen. Eine Senkrechte Linie, zwei waagerechte Linien und zwei Kreise an den Ecken. Also die graphische Darstellung des Schlägers hat da natürlich keine Kreise sondern abgerundete Ecken aber das mathematische Modell hat da Kreise, der Einfachheit wegen.
Nennen wir die beiden Kreise mal k1 und k2.
Dann sieht der Algorithmus ungefähr so aus. (für den linken Schläger)
Java:
if(ball.collideswith(schlaeger) {
    if(ball.y >= k1.y && ball.y <= k2.y) ball.speed.x = -ball.speed.x;
    else if(ball.x <= k1.x) ball.speed.y = -ball.speed.y //k1.x und k2.x sind immer identisch
    else {  //Kollision mit einem Kreis
        Kreis k = k1;
        if(ball.y > k2.y) k = k2;
        //denk dir eine Linie vom Mittlepunkt des Kreises zum Mittelpunkt des Balls.
        //wir brauchen jetzt den Winkel zwischen dieser Linie und der x Achse
        double w1 = Math.atan2(ball.y-k.y, ball.x-k.x);
        //und den Winkel in dem sich der Ball relativ zur x Achse bewegt
        double w2 = Math.atan2(ball.speed.y, ball.speed.x);
        double einfallswinkel = w2-w1;
        ball.speed.x = -ball.speed.x;
        ball.speed.y = -ball.speed.y;
        ball.speed.rotate(-2*einfallswinkel);
    }
}
Und einen Vektor rotiert man so
Java:
rotate(Vector v, double angle) {
    double sin = Math.sin(angle);
    double cos = Math.cos(angle);
    double newX = v.x*cos - v.y*sin;
    double newY = v.x*sin + v.y*cos;
    v.x = newX; v.y = newY;
}

Das ganze lässt sich übrigens auch ohne die Verwendung von Trigonometrie lösen, mit reiner Vektorrechnung.
 

Java-Jr.

Mitglied
Zum letzten Codestück: Mach' es so wie Crian es geschrieben hat. (Das abs ist überflüssig, das pow ist langsamer als x*x, und wenn man wirklich den Abstand braucht (und nicht wie in Crians Beispiel der quadrierte Abstrand ausreicht) sollte man sqrt statt pow(...,0.5) verwenden)

Super, das ist die Art von Tipps die ich wohl auch ziemlich nötig habe :toll:
-Ja ich hatte wohle Angst, dass die Koordinaten ins negative rutschen könnten, deshalb abs, aber da hab ich die wohl mit der x/y Geschwindigkeit verwechelt :bloed:
das mit dem sqrt glaube ich dir jetzt einfach mal so......

So, ich habe eine physikalisch korrekte (denke ich mal.) Anwendung gefunden.
Die hab ich mal aufgemalt, ich bin echt nicht gut mit Paint und es sieht schlimmer aus, als es komplex ist.

http://img213.imageshack.us/img213/2613/pongphysik.png

Legende:
S - Schläger
M - Mittelpunkt des Balles
T1 - Tangente des Balles im Kollisionspunkt
T2 - Parallele der Tangente T1 durch den Mittelpunkt M
R1 - Ursprügliche Bewegungsrichtung des Mittelpunktes com Ball
R2 - Neue Bewegungsrichtung
alpha - Winkel Zwischen T1 und R1
alpha' - Gleicher Winkel, abgetragen von T2, der ergibt R2

Damit gilt alpha = alpha' Einfallswinkel gleich Ausfallswinkel. Selbst wenn das physikalisch stimmt, wie zur Hölle schaff ich es, das umzusetzen?!
 

Java-Jr.

Mitglied
So ich hab mich nochmal umgesehen:

im Tafelwerk steht: cos(alpha) = (a * b) / (|a| * |b|) wobei a und b die beiden Vektoren sind und alpha der Winkel zwischen ihnen, für den gilt: 0<= alpha <= 180°

Das rechne ich also für die T1 und R1, weiß nur noch nicht, wie ich von denen je einen Vektor bekomme.
Dann rotiere ich die Richtung des Balles, wie es Dr.Zoidberg gezeigt hat und tadaaaa, ganz korrekte Richtung...oder?
 

Marco13

Top Contributor
Was heißt "von denen"? Der Vektor für die Bewegungsrichtung R1 ist schlicht die Geschwindigkeit. Der Vektor für T1 ist der Vektor, der senkrecht auf der Differenz zwischen dem Kreismittelpunkt und dem Berührungspunkt liegt. WAS der Berührungspunkt ist (bzw. wie man ihn ausrechnet) müßte man sich noch überlegen, bzw. man findet sicher VIEELLL im Web dazu. Irgendwie hab' ich ein etwas flaues Gefühl bei dem Versuch, Gedanken dieser Art auf einem Bild basieren zu lassen, das (speziell in bezug auf den Berührungspunkt) "falsch" ist... aus dem Bauch raus würde ich sagen, dass R2 im Bild stimmen könnte (weil der Berührungspunkt wohl eher auf der Oberseite des Schlägers liegen würde), aber ... wenn man dieses "richtige" Ergebnis aus den "falschen" Eingaben bekommt, bedeutet das dann nicht, dass die Rechnung falsch sein muss? Vermutlich müßte ich da jetzt auch mal ausführlicher Websuchen und Zeichnen....
 

Java-Jr.

Mitglied
Ich denke nicht, dass es schwer wäre, den Berührungspunkt (ich denke mal, du meinst jetzt aud der Kreisbahn, der am Schläger ist ja klar ;)) herauszufinden, das kannst du ja auch selbst ausprobieren:
Du zeichnest den Padder und eine Linie R1, die sich seiner Ecke auf weniger als den Radius des Kreises annähert, der erste Punkt, bei dem der Abstand von R1 zur Ecke des Schlägers <= dem Radius des Kreises ist, ist der Mittelpunkt dann zeichnest du von diesem Punkt aus eine Linie zur Ecke des Schlägers, die muss dann den Kreisbogen im Berührungspunkt schneiden (mir helfen solche schematischen Skizzen immer sehr).

Erklärt das was, oder habe ich die Schwierigkeit nur nicht verstanden?
 

Marco13

Top Contributor
Wenn es nur um die Ecke geht... Ähm. Vielleicht reden wir aneinander vorbei. Ich denke, dass es im angehängten Bild schwierig ist, den Zeitpunkt t=??? der Kollision und die damit verbundenen Roten Punkte zu bestimmen - also vermutlich das, was du als
"der erste Punkt, bei dem der Abstand von R1 zur Ecke des Schlägers <= dem Radius des Kreises ist"
beschrieben hast. Wenn ein Rechteck und ein Kreis und eine Bewegung des Kreises (und eine Bewegung des Rechtecks!) gegeben sind, wüßte ich nicht, wie man das machen sollte, außer annähernd mit Intervallhalbierung, oder mit vieeeel Mathematik. Aber wie gesagt, man findet dazu sicher viel im Web (habe bisher noch NIX dazu gesucht, vielleicht denke ich auch nur (mal wieder) zu kompliziert :oops: )
 

Anhänge

  • Pong01.PNG
    Pong01.PNG
    4,1 KB · Aufrufe: 34

DrZoidberg

Top Contributor
Ich hatte gestern schon geposted wie man die Kollision zweier Kreise berechnet. Der Code benötigt weder den Berührungspunkt, noch den Radius der Kreise. Und da er unabhängig vom Radius ist, funktioniert er auch für Kreise mit dem Radius 0, also Ecken. Alles was du brauchst ist der Vektor vom Ball zur Ecke und den Geschwindigkeitsvektor des Balls. Der Winkel zwischen beiden ist der Einfallswinkel. Dann rotierst du den Geschwindigkeitsvektor einfach um zwei mal Einfallswinkel und kehrst seine Ruchting um. Das ist alles.
 

Java-Jr.

Mitglied
Kann sein Marco, Ich habe ja eine nahezu konstante, in dem Frame, wenn ich rechne exakte Geschwindigkeit für den Ball.
Dann könnte ich zum Beispiel abfragen, ob Kreis und Schläger sich überlappen und dann kann man ja das kleine Stück auf der Bahn des Balls zum Kollisionspunkt zurückrechnen.
 

Java-Jr.

Mitglied
Ok, DANKE, Zoidberg, was Math.atan2() ist werde ich schon rausfinden. Ich hab mir den Code wahrscheinlich gar nicht genug angesehn, um zu sehen, das das schon größtenteils die Lösung ist :p

Aber: Marco und ich wollten einfach den Berührungspunkt genau herausfinden, weil man dann von ihm ausgehen könnte (für die weitere Bewegung des Balls) und das ist ein Bisschen genauer, als aus der Überlappung zu starten.

Den Radius braucht man eigentlich wirklich nicht, außer bei der KollisionsERKENNUNG und die ist in deinem Beispiel nicht dabei, deshalb brauchst du keinen Radius.

Dann noch eine Frage: das Ball/Kreis.y/x in deinem Beispiel ist das die y/x-Koordinate der oberen Ecke des Rechtecks um das jeweilige Element oder des Mittelpunktes?
 

DrZoidberg

Top Contributor
Das ist jeweils der Mittelpunkt. Also wenn du abgerundete Ecken an deinem Schläger hast wäre das der Mittelpunkt der Rundung. Bei nicht abgerundeten Ecken wäre es genau die Ecke. Du kannst dir die Ecke eines Rechtecks einfach als Kreis vorstellen, der auch einen Radius von 0 haben kann.
Und Math.atan2(y,x) berechnet den Winkel zwischen einem Vektor und der x Achse.
Den Berührungspunkt kannst du am einfachsten über eine binäre Suche finden.
Das geht so
Java:
if(ball.collidesWith(Schlaeger)) {
    Vector high = ball.pos;
    Vector low = ball.pos - ball.speed;
    while(length(high - low) > 0.001) {
        Vector middle = (high + low)/2;
        ball.pos = middle;
        if(ball.collidesWith(Schlaeger)) {
            high = middle;
        } else {
            low = middle;
        }
    }
    Vector ballPositionAtCollision = low;
}
Also ballPositionAtCollision ist dann die genaue Position, die der Ball zum Zeitpunkt der Kollision hat. Daraus müsste sich der Berührungspunkt dann leicht ermitteln lassen.
 
Zuletzt bearbeitet:
S

Spacerat

Gast
Also für das ehrwürdige Ur-Pong reichte ein "<Rectangle>.intersects()" für Kollisionsabfragen vollkommen aus, zumal der Ball ja nicht rund war. Für einen runden Ball müsste man nun Aufgrund seines Radiusses sämtliche Punkte seines Umfangs mit "<Rectangle>.contains(point)" überprüfen. Da das aber zu viel Rechnerei ergeben würde, könnte man auch ein BitSet als "Hitbox" verwenden in welchen die Punkte des Balls mit true und die Punkte des Hintergrunds mit false stehen. Wenn dann "<Rectangle>.intersects()" zutrifft, prüft man, ob im Bereich "<Rectangle>.intersection()" der Hitbox ein true auftaucht. Ist dies der Fall, liegt eine Kollision vor. Das Ganze kann man auch für "FutureFrames" machen, sollte aber für Pong nicht nötig sein.
[EDIT]Wenn der Schläger auch abgerundet ist, wird für diesen natürlich auch 'ne Hitbox benötigt.[/EDIT]
[EDIT]...und wer ganz Clever ist, verwendet als Hitbox den Alpha-Kanal der Bilder (z.B. Alpha < 128 bedeutet Hintergrund, Alpha >= 128 bedeutet sichtbar).[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:

Java-Jr.

Mitglied
Sooooo, ich denke mal, das wars also, DANKE!

Noch eine kleine Frage, bevor ich das hier als erledigt markiere: ist es schöner/performanter, was auch immer, ein Array für [x,y] Vektoren oder einen Vektor aus irgendeiner Bibliothek?
 

DrZoidberg

Top Contributor
Wieso ein Array? Ich würde da eine Vektor Klasse erstellen.
Sieh dir mal das Programm hier an.
[Java] ball collision - Pastebin.com
Du kannst Bälle ins Spiel bringen indem du mit der Maus klickst, den Mauszeiger in die Richtung bewegst in der sich der Ball bewegen soll und dann loslässt. Verwendet übrigens einen anderen Kollisionsalgorithmus, der auf Vektorrechnung beruht und universeller einsetzbar ist.
 

Marco13

Top Contributor
Ich hatte gestern schon geposted wie man die Kollision zweier Kreise berechnet

Der eine Kreis ist aber bewegt, und das andere ist evtl. keine Ecke, sondern eine Kante. Es ist nicht so einfach. Aber natürlich kann jeder erst die vermeintlich einfachen Lösungen durchprobieren, das steht jedem frei. (Danach kommt man z.B. bei der binären Suche an, was im Vergleich zu einer analytischen Lösung natürlich auch noch relativ einfach ist)
 

DrZoidberg

Top Contributor
Also der Code, den ich am Freitag geposted habe, funktioniert nur wenn einer der beiden Kreise unbeweglich ist, der andere - der Ball - kann aber beweglich sein. Und der unbewegliche Kreis kann beliebig klein sein also z.B. auch eine Ecke mit Radius 0. Und natürlich muss man erst überprüfen, ob der Ball mit einer Ecke oder mit einer Kante kollidiert. Also ich verstehe nicht wo du da ein Problem siehst. Und was hast du gegen Einfachheit? Ich sehe keinen Sinn darin Dinge künstlich zu verkomplizieren.
 

Java-Jr.

Mitglied
Wenn sich der Schläger in Richtung der Kollisions-Ecke bewegt, würde ich irgendwie die Differenz seiner Geschwindigkeit von der x-Geschindigkeit des Balls zu beiden Geschwindigkeiten des Balls addieren, aber so, dass sie ihr Verhältnis, also die eigentliche Richtung beibehalten....
 

Marco13

Top Contributor
Wenn sich der Schläger in Richtung der Kollisions-Ecke bewegt, würde ich irgendwie die Differenz seiner Geschwindigkeit von der x-Geschindigkeit des Balls zu beiden Geschwindigkeiten des Balls addieren, aber so, dass sie ihr Verhältnis, also die eigentliche Richtung beibehalten....

Ja, das kann man so machen. Bewegung ist so ziemlich das relativste, was es gibt :D


@DrZoidberg: Wie gesagt, die Option der binären Suche besteht praktisch immer, und macht das ganze sehr leicht, aber ggf. ineffizient und ungebau im Vergleich zu einer analytischen Lösung. Die Binäre Suche würde aber die Frage "Kante oder Ecke?" relativ leicht mitbehandeln können, deswegen ist das hier vermutlich die geeignetste Wahl.
 

Java-Jr.

Mitglied
Also, ich hab das jetzt so gemacht:

Java:
float tangente = (float) Math.atan2(-(ball.Y - padder.Y), ball.X -padder.X + padder.width ); //Tangente zum Kollisionspunkt (muss orthogonal zum radius des Kreises, der dahin geht sein, deshalb von diesem Radius die x/y vertauscht und eins von beiden minus genommen.
			float richtung = (float) Math.atan2(ball.Speed[0], ball.Speed[1]);
			
			float alpha = Math.abs(tangente-richtung); //berechnet den Einfallswinkel
			
			rotate(ball.Speed, tangente + alpha); // rotiert um den Einfallswinkel augehend von der Tangente, von der der Ball ja "gedacht" abprallt

Aber das funktioniert überhaupt nicht gut.
Zoidberg, deine Kollisions-Reaktion hat auch nicht sehr realistisch ausgesehen..... Ich weiß auch wirklich nicht genau,in was für einer Einheit diese Math.atan2() den Winkel ausgibt, Grad ist das nicht, aber wie ein korrektes Bogenmaß siehts hier auch nicht aus....
Exploring Math.atan2( y, x )
 

DrZoidberg

Top Contributor
Der Code, den du da verwendet hast ist ja auch völlig anders als meiner.
Teste mal das Programm hier
[Java] Java Pong - Pastebin.com
Verwendet genau den Algorithmus, den ich dir vorgeschlagen hatte. Und das Abprallverhalten an der Ecke scheint mir realistisch zu sein.

Alle Methoden in Math verwenden standardmässig rad für Winkel.
Bsp.
Java:
double grad = 30;
double rad = Math.toRadians(grad);
double x = Math.cos(rad);
double y = Math.sin(rad);
System.out.println(Math.toDegrees(Math.atan2(y,x)));
[/Java]
Ausgabe:
29.999999999999993
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Kollision von 2 Objekten Java Basics - Anfänger-Themen 2
C Kollision zweier Rechtecke, Schnittpunkte bestimmen Java Basics - Anfänger-Themen 25
dome385 Ball Ball Kollision physikalisch korrekt Java Basics - Anfänger-Themen 5
L Grafik Kollision Detektierung Java Basics - Anfänger-Themen 4
S Problem bei Kollision zwischen Array-objekten! Java Basics - Anfänger-Themen 2
B Kollision tritt nie ein ? Java Basics - Anfänger-Themen 15
D Frage zu Kollision Java Basics - Anfänger-Themen 3
T Kleines Game mit Kollision Java Basics - Anfänger-Themen 2
J Ball->Wand Kollision - Ball bleibt an Decke und Boden hängen Java Basics - Anfänger-Themen 2
J Tilemap Kollision Java Basics - Anfänger-Themen 25
T Kollision bei Wänden Java Basics - Anfänger-Themen 2
M OOP Kollision entdecken Java Basics - Anfänger-Themen 4
TheKing Tile Map - Kollision Java Basics - Anfänger-Themen 2
V Rennspiel, Kollision Java Basics - Anfänger-Themen 19
I Kollision zweier Rechtecke Java Basics - Anfänger-Themen 9
M Länge eines Arrays als Variable speichern möglich? Java Basics - Anfänger-Themen 14
P Objekt einer Methode eines anderen Objektes übergeben Java Basics - Anfänger-Themen 5
P Wie kann ich beispielsweise Speicherstände eines Spiels DAUERHAFT in meinem Programm speichern? Java Basics - Anfänger-Themen 3
laxla123 Eigenschaften eines Algorithmus (determiniert vs.. deterministisch) Java Basics - Anfänger-Themen 2
monsterherz Ablauf der Erstellung eines Java Programmes Java Basics - Anfänger-Themen 17
monsterherz Fehler Semikolon fehlt - ich weiss aber nicht wo da noch eines hin sollte... Java Basics - Anfänger-Themen 21
J Farbe des Striches eines TitledBorders ändern Java Basics - Anfänger-Themen 2
pc pc pc pc pc letztes Element eines Arrays n Java Basics - Anfänger-Themen 3
walid Öffnungszeiten eines Geschäftes Java Basics - Anfänger-Themen 3
paulen1 Best Practice "Unchecked Assignment" Warnung beim erstellen eines 2D Arrays of Arraylists Java Basics - Anfänger-Themen 2
T Probleme beim Import eines Git-Repos Java Basics - Anfänger-Themen 2
U Eigenschaft eines JTextfiels per ActionListener ändern... Java Basics - Anfänger-Themen 2
B Synchronisation eines kleinen Museums Java Basics - Anfänger-Themen 47
krgewb Breite und Höhe eines Bildes in base64 auslesen Java Basics - Anfänger-Themen 3
Sachinbhatt Was ist die Notwendigkeit eines Sammlungsframeworks in Java? Java Basics - Anfänger-Themen 2
N Textdatei aus Resourcen-Ordner eines Projekts/ jar-file lesen Java Basics - Anfänger-Themen 4
B Produkt eines double - streams Java Basics - Anfänger-Themen 3
B Attribute eines Objekts einer Klasse durch statische Methode einer 2. Klasse ändern? Java Basics - Anfänger-Themen 32
S Variablen Letzte Zeile eines Strings entfernen Java Basics - Anfänger-Themen 1
D Inhalt eines Arrays ausgeben Java Basics - Anfänger-Themen 7
A Jedes zweite Element eines Arrays entfernen Java Basics - Anfänger-Themen 30
sserio Java Fx, wie erstellt man einen EventHandler, der durch das Drücken eines Button Texte in eine Table view einfügt Java Basics - Anfänger-Themen 17
J Größe eines Strings in Pixel Java Basics - Anfänger-Themen 18
M Parse-Tree eines statements darstellen Java Basics - Anfänger-Themen 0
H Java verkettete Liste, Wert eines Index zurückgeben Java Basics - Anfänger-Themen 1
bluetrix Programmieren eines Bots für Zahlen-Brettspiel Java Basics - Anfänger-Themen 9
J Hinzufügen eines Objektes in ein Objekt-Array Java Basics - Anfänger-Themen 62
M Wie kann die Implementation einer Methode den Wert eines Attributs vermindern? Java Basics - Anfänger-Themen 3
A Rekursive Implementation eines Codes Java Basics - Anfänger-Themen 4
H String Repräsentation eines Rechtecks mit Instanz-Methode Java Basics - Anfänger-Themen 8
M Konstruktor ohne Übergabe eines Wertes Java Basics - Anfänger-Themen 7
M Wie kann ich in einem Konstruktor die Methode eines anderen Interfaces mit den jeweiligen Parametern aufrufen? Java Basics - Anfänger-Themen 8
M Wie erreiche ich das Vorwärtsgehen eines Roboters? Java Basics - Anfänger-Themen 2
M Wie erreiche ich es das Vorwärtsgehen eines Roboters? Java Basics - Anfänger-Themen 0
R While-Loop der die Einträge eines Arrays in umgekehrter Reihenfolge anzeigt Java Basics - Anfänger-Themen 3
A Optimierung eines Programms: Mergen der Dateien Java Basics - Anfänger-Themen 23
melisax Alle Möglichkeiten eines Wortes angeben Java Basics - Anfänger-Themen 3
A Java, verarbeitung eines xml-files Java Basics - Anfänger-Themen 2
C Fehler beim erstellen eines Objektes Java Basics - Anfänger-Themen 3
B Konkatenieren eines Strings und inkremtierenden Zahl zu einer INT Variablen Java Basics - Anfänger-Themen 7
F Initialisieren eines Web-Mp3 Players in Tabs durch "booleans" erst wenn Tab geöffnet wird ...? Java Basics - Anfänger-Themen 1
P Drei Zahlen eines Würfelspiels auswerten Java Basics - Anfänger-Themen 7
C Brauche Hilfe beim Schreiben eines Programmes :/ Java Basics - Anfänger-Themen 1
C initialisieren eines arrays richtiger Größe und mit geeignetem Datentyp Java Basics - Anfänger-Themen 26
C Überprüfen eines Programms auf Syntaxfehler Java Basics - Anfänger-Themen 3
S Wie kann ich den Bereich eines Integers begrenzen? Java Basics - Anfänger-Themen 2
nonickatall Grundsätzliches Verständnisproblem des Aufbaus eines Programms Java Basics - Anfänger-Themen 19
B Downgrade eines bestehenden Projektes Java Basics - Anfänger-Themen 5
amelie123456 Geschwindigkeit der Methode bewegeDich eines Objekts ändern Java Basics - Anfänger-Themen 2
D Hilfe beim Erzeugen eines Arrays NullPointerException wird ausgelöst Java Basics - Anfänger-Themen 11
J maximaler Wert eines Integers Java Basics - Anfänger-Themen 14
TimoN11 IntelliJ , Ausgabe von einem Quellcode in Eingabe eines Quellcodes Java Basics - Anfänger-Themen 1
Z Rückgabe eines Values in umgekehrte richtung Java Basics - Anfänger-Themen 5
L Methode zum invertieren eines Arrays Java Basics - Anfänger-Themen 7
B fragen zu Aufbau eines UML-Klassendiagramm Java Basics - Anfänger-Themen 1
eleonori Durchschnitt aller Werte eines Baums berechnen Java Basics - Anfänger-Themen 5
M Benutzereingabe eines Codes verbessern Java Basics - Anfänger-Themen 3
B Modulo-Operator anhand eines Beispieles erklären Java Basics - Anfänger-Themen 7
J Verschieben von Buchstaben in einem String um vorgegebene Anzahl von Zeichen innerhalb eines weiteren String Java Basics - Anfänger-Themen 12
F Auf Variablen eines Konstruktors zugreifen Java Basics - Anfänger-Themen 4
Kawastori Größe eines Arrays bestimmen Java Basics - Anfänger-Themen 13
Lena_2611 Vergleich von Array1 Index mit Array2 Wert und erzeugen eines neues Arrays Java Basics - Anfänger-Themen 8
A Teilarrays eines 2D-Arrays sortieren Java Basics - Anfänger-Themen 4
marcooooo Separator zwischen allen Zeichen eines Strings einfügen Java Basics - Anfänger-Themen 29
C Wie kann ich Versionen eines Projektes in Eclipse erstellen? Java Basics - Anfänger-Themen 3
yoskaem Text Color durch Klicken eines Buttons in anderer Activity ändern Java Basics - Anfänger-Themen 2
A Teilen eines Arrays Java Basics - Anfänger-Themen 5
DorFey Sortieren eines mehrdimensionalen Arrays Java Basics - Anfänger-Themen 8
P Klasse hat keinen Zugriff auf getter/setter-Methoden eines Objektes Java Basics - Anfänger-Themen 9
R Löschen und ausgeben eines Teilbaums Java Basics - Anfänger-Themen 3
J Alle Werte eines Strings zusammen addieren Java Basics - Anfänger-Themen 15
M Hilfe bei Strukturierung eines Buchungssystems Java Basics - Anfänger-Themen 3
M Erstellen eines insets Objekts, GridBagLayout Java Basics - Anfänger-Themen 13
M Rückgabe eines Arrays Java Basics - Anfänger-Themen 10
Z Erste Schritte Indexe innerhalb eines Arrays zusammensählen Java Basics - Anfänger-Themen 14
W Random Zahl unter Berücksichtung eines Durchschnitts Java Basics - Anfänger-Themen 7
N Länge eines Arrays in einem Objekt testen Java Basics - Anfänger-Themen 51
A Freie Stelle eines Arrays Java Basics - Anfänger-Themen 17
C Erstellen eines Widerstandsnetzwerks Java Basics - Anfänger-Themen 10
C Methode Seiten tauschen eines erstellten Rechtecks mit Seite A und B Java Basics - Anfänger-Themen 9
R Zugriff auf den Index eines Arrays, welches ein Objekt ist. Java Basics - Anfänger-Themen 4
J Problem bei der Programmierung eines Tannenbaums Java Basics - Anfänger-Themen 9
F Berechnung der Rektaszension und Deklination eines Sterns Java Basics - Anfänger-Themen 7
1 Erste Schritte Was denkt ihr über eines meiner ersten Javaprogramme? Java Basics - Anfänger-Themen 2
A Problem bei returnen eines Wertes Java Basics - Anfänger-Themen 6

Ähnliche Java Themen

Neue Themen


Oben