Winkel und Kräfte berechnung bei bewegten Objecten
Übersicht

![]() |
BobBetreff: Winkel und Kräfte berechnung bei bewegten Objecten |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo Forum,
da ich leider in Mathe nie besonders gut war beschäftigt mich folgendes Problem. Ausgangssituation: Ein Art BreakOut Spiel. Eine Kugel titscht in einem geschlossenen Raum hin und her. Sie prallt an den Wänden, verstreuten Gegenständen und dem „Schläger „ des Spielers ab. Es gibt in diesem Forum mittlerweile einige Nachrichten zu dieser Problematik. Allerdings beschäftigen sich die meisten davon lediglich mit dem Abprall der Kugel an den Wänden. Diese wird bei mir relativ simpel dadurch gelöst (wie hier mehrfach erwähnt) die x und y Geschwindigkeit einfach umzukehren wenn x oder y <> Screen. Das Ergebnis ist FÜR DIE WÄNDE ausreichend. Hier wird lediglich auf Ball < ScrennX , Ball > screenX, Ball >ScreenY, Ball < ScreenY Geprüft. (Screnn X, ScrennY entsprechen der aktuellen Auflösung des Bildschirms) Der Ball muss sich aber beim Aufprall auf innerhalb des Screens platzierten Gegenständen anders verhalten. Es entsteht sonst mit der Zeit eine, sich kontinuierlich wiederholende Flugbahn. Noch (für mich) komplizierter wird es wenn der Ball auf einen weitern, sich bewegenden Ball (Billiard mässig) trift. Hier treffen 2 Kräfte unterschiedlicher Stärke aufeinander. Berühren sich die beiden Bälle bei einem Aufprallwinkel von 180 Grad mit gleicher Geschwindigkeit, müssten (glaube ich) ja beide Bälle zum Stillstand kommen da sich die Kräfte gegenseitig aufheben. 1.Wie also kann bei Kollision 2er, sich bewegender, Bälle festgestellt werden wohin sie sich nach der Kollision mit welcher Geschwindigkeit bewegen. Eine externe Physik Engine ist für mich keine Lösung. Danke für Tipps. Hier noch ein bischen Code. Code: [AUSKLAPPEN] Const ScreenX = 640 Const ScreenY = 480 Const DM = 40 ;Durchmesser Const Radius = DM /2 ;Radius Graphics Screenx,ScreenY,16 SetBuffer BackBuffer() Type ball Field img Field x#,y# Field sx#,sy# Field Speed# Field fest End Type For i=0 To 2 b.ball = New ball b\img = CreateImage(dm,dm) HandleImage b\img, Radius,RAdius SetBuffer ImageBuffer(b\img) Color 255,0,0 Oval 0,0,40,40,1 b\speed = 1 b\x = Rand(50,Screenx) b\y = Rand(0,460) b\sx = Sin(Rand(360))*b\speed b\sy = Cos(Rand(360))*b\speed b\fest = 0 Next b.ball\sx = 0 b.ball\sy = 0 b\fest = 1 SetBuffer BackBuffer() While Not KeyHit(1) For b.ball = Each ball ;Abprall an den Wänden If b\x < Radius Then b\sx = Cos(b\sx)*b\speed If b\x > Screenx-Radius Then b\sx = Cos(b\sx)*-b\speed If b\y > ScreenY-Radius Then b\sy = Cos(b\sy)* -b\speed If b\y < Radius Then b\sy = Cos(b\sy)* b\speed For g.ball = Each ball If Not Handle(g) = Handle(b) Then If ImagesCollide (b\img,b\x,b\Y,0, g\Img,g\x,g\y,0) Then ;Auprallwinkel grad# = winkel(b\x ,b\y , g\x, g\y) If Not g\fest = 1 Then ; mein kläglicher Versuch die richtigen winkel festzustellen. Bähhhhh g\sx = Sin(grad) * g\speed g\sy = Cos(grad) * g\speed b\sx = Cos(grad) * g\speed b\sy = Sin(grad) * g\speed EndIf EndIf EndIf Next b\x = b\x + b\sx b\y = b\y + b\sy DrawImage b\img, b\x, b\y Next Flip Cls Wend End Function Winkel(x1,x2,y1,Y2 ) ;-------------------------- grad =ATan2(y1 -y2, x1-x2)-90 If grad < 0 Then grad = grad+360 Return grad End Function |
||
![]() |
Markus2 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hier nen Beispiel ,
habe aber ein wenig dran rumgespielt ... Code: [AUSKLAPPEN] ;------------------------------------------ ;2D COLLISION DEMO CODE ;------------------------------------------ ; kein Original mehr ... ; By Joseph 'Phish' Humfrey ; This type of collision response isn't ; just useful for pool and billiard style ; games, and in fact, I didn't write it for ; that reason at all. I wrote it because I ; needed to have collision for the space ; ships in my game 'Unity'. When their ; shields are up, they use this relatively ; simple method. It can be used for almost ; anything - player character bouncing off ; enemies in a platform game, to space ; ship collision, to a game which does ; actually involve balls. The basic ; algorithm which I used would work for ; both 2d and 3d, so if you would like to ; see it, email me at phish@aelius.com ;------------------------------------------ ; The actual code which works out what ; happens after a collision is in the ; UpdateCirclePhysics() function. ;------------------------------------------ ; Enjoy! ;------------------------------------------ ;------------------------------------------ Graphics 800, 600, 16, 2 SetBuffer BackBuffer() SeedRnd MilliSecs() ;------------------------------------------ ; MAIN DATA TYPE ;------------------------------------------ ; This exact type isn't supposed to be used ; Instead, you should use some of the fields ; in your own type, or just use this one ; for reference, to see what each field does Type circle Field x#, y# ;position Field dx#, dy# ;x and y speeds Field radius# ;radius of circle Field mass# ;mass of circle End Type ;------------------------------------------ ;------------------------------------------ ;------------------------------------------ ; SET UP BALLS INTO A POOL STYLE ARRANGEMENT ; FOR DEMO ;------------------------------------------ .Setup ballTriangleSize=10 For xloop = ballTriangleSize To 1 Step -1 For yloop = 1 To xloop c.circle = New circle c\x = (5-xloop)*27 + 200 c\y = yloop*31-(xloop*31)/2.0 + 300 c\dx=0 c\dy=0 c\radius = 2 c\mass = 50 Next Next ;Cue ball (smaller so you know which it is :) cue.circle = New circle cue\x = 800 cue\y = 300 +Rnd(-10,10) cue\dx = -20 cue\dy = Rnd(4)-2 cue\radius = 2 cue\mass = 10 ;------------------------------------------ ;------------------------------------------ ;------------------------------------------ ;MAIN LOOP ;------------------------------------------ ; This is the main While..Wend game loop While Not KeyDown(1) Cls UpdateCirclePhysics() RenderCircles() ;------------ ; Reset button Text 10, 10, "Press a mouse button to reset." Text 10, 25, "Press Esc to exit." If GetMouse() Then ;Cls For c.circle = Each circle Delete c Next Goto setup End If ;------------ Flip Wend ;------------------------------------------ ;------------------------------------------ End ;------------------------------------------ Function UpdateCirclePhysics() ;------------------------------------------ ; This is the main physics function for the ; circles. It contains the very basic ; movement physics as well as the collision ; response code. ;------------------------------------------ For c.circle = Each circle ;update positions c\x=c\x+c\dx c\y=c\y+c\dy ;gradually slow down c\dx=c\dx*0.99 c\dy=c\dy*0.99 ;------------------------------------------ ;COLLISION CHECKING ;------------------------------------------ ; Check each circle in the loop against ; every other (c against c2) For c2.circle = Each circle collisionDistance# = c\radius+c2\radius actualDistance# = Sqr((c2\x-c\x)^2+(c2\y-c\y)^2) ;Collided or not? If actualDistance<collisionDistance Then collNormalAngle#=ATan2(c2\y-c\y, c2\x-c\x) ;Position exactly touching, no intersection moveDist1#=(collisionDistance-actualDistance)*(c2\mass/Float((c\mass+c2\mass))) moveDist2#=(collisionDistance-actualDistance)*(c\mass/Float((c\mass+c2\mass))) c\x=c\x + moveDist1*Cos(collNormalAngle+180) c\y=c\y + moveDist1*Sin(collNormalAngle+180) c2\x=c2\x + moveDist2*Cos(collNormalAngle) c2\y=c2\y + moveDist2*Sin(collNormalAngle) ;------------------------------------------ ;COLLISION RESPONSE ;------------------------------------------ ;n = vector connecting the centers of the circles. ;we are finding the components of the normalised vector n nX#=Cos(collNormalAngle) nY#=Sin(collNormalAngle) ;now find the length of the components of each movement vectors ;along n, by using dot product. a1# = c\dx*nX + c\dy*nY a2# = c2\dx*nX + c2\dy*nY ;optimisedP = 2(a1 - a2) ; ---------- ; m1 + m2 optimisedP# = (2.0 * (a1-a2)) / (c\mass + c2\mass) ;now find out the resultant vectors ;r1 = c1\v - optimisedP * mass2 * n c\dx = c\dx - (optimisedP*c2\mass*nX) c\dy = c\dy - (optimisedP*c2\mass*nY) ;r2 = c2\v - optimisedP * mass1 * n c2\dx = c2\dx - (optimisedP*c\mass*-nX) c2\dy = c2\dy - (optimisedP*c\mass*-nY) End If Next ;------------------------------------------ ;------------------------------------------ If 1=1 Then ;Wand Colli An/Aus ;Simple Bouncing off walls. If c\x<c\radius Then c\x=c\radius c\dx=c\dx*-0.9 End If If c\x>GraphicsWidth()-c\radius Then c\x=GraphicsWidth()-c\radius c\dx=c\dx*-0.9 End If If c\y<c\radius Then c\y=c\radius c\dy=c\dy*-0.9 End If If c\y>GraphicsHeight()-c\radius Then c\y=GraphicsHeight()-c\radius c\dy=c\dy*-0.9 End If EndIf Next End Function ;------------------------------------------ Function RenderCircles() ;------------------------------------------ ; Simple function draws all the circles ; on the screen. ;------------------------------------------ For c.circle = Each circle If c\radius=15 Then Color 200, 50, 50 Else Color 255, 255, 255 Oval c\x-c\radius, c\y-c\radius, c\radius*2, c\radius*2,False Next End Function ;------------------------------------------ ;------------------------------------------ |
||
![]() |
Bob |
![]() Antworten mit Zitat ![]() |
---|---|---|
Thanks.
Ich werd's mir mal reinziehen und studieren. |
||
![]() |
Bob |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi Markus2
wollt nochmal danke sagen. Bin jetzt erst dazu gekommen mich mal um den Code zu kümmern. (Dabei kümmere ich mich in den letzten Tagen auch um sonst jeden schei...) Ich hab ihn ein bischen meinen bedürfnissen angepasst. Nun sieht alles viel realistischer aus. ![]() Bob |
||
![]() |
Markus2 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Jo,
aber eigentlich solltest du Joseph 'Phish' Humfrey danken ![]() |
||
![]() |
Travis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Sorry, dass ich diesen alten Thread hier wieder hervorgrabe, aber ich wollte keinen neuen aufmachen. 8) Für ein neues Projekt habe ich mich jetzt auch einmal mit diesem schönen Beispiel, dass Markus2 hier gepostet hat auseinandergesetzt. ![]() Ich habe allerdings massive Probleme, die Funktionsweise der Kollisionsabfrage und der Berechnung der neuen Bewegungsrichtungen zu verstehen. BlitzBasic: [AUSKLAPPEN]
Ab "Position exactly touching, no intersection" verstehe ich nur noch Bahnhof. Was genau bedeuten denn die Variablen moveDist1# und moveDist2#? BlitzBasic: [AUSKLAPPEN] ;Position exactly touching, no intersection Ich vermute mal hier wird die Überschneidung der beiden Kugeln ausgeglichen und die Kugeln werden exakt nebeneinander platziert. Ist ja soweit noch irgendwie logisch, aber was genau hat die Masse damit zutun? Alles was danach kommt, verstehe ich überhaupt nicht. Was bedeutet a1 bzw a2? Was hat es mit optimisedP auf sich? Ich habe da echt keinen Durchblick. Diesen Code würde ich gerne für mein neues Projekt verwenden - ist soweit auch kein Problem - nur möchte ich ihn auch gerne verstehen. Vielleicht ist ja jemand so nett und gibt einem mathematisch durchschnittlich begabtem Menschen etwas Nachhilfe. ![]() |
||
www.funforge.org
Ich hasse WASD-Steuerung. Man kann alles sagen, man muss es nur vernünftig begründen können. |
![]() |
rambo256 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also ich denke,das dieses OptimisedP den Impuls ausrechnet
P = m*v V' = Geschwindigkeit nach dem Aufprall V' = (v1*m1 - v2*m2) ----------------------- m1+m2 V' steht nun für OptimisedP v(=Geschwindigkeit) rechnet der so aus: BlitzBasic: [AUSKLAPPEN] a1# = c\dx*nX + c\dy*nY Er addiert die beiden Vektoren,das ergibt dann V1 (=Geschwindigkeit) BlitzBasic: [AUSKLAPPEN] optimisedP# = optimisedP# = (2.0 * (a1-a2)) / (c\mass + c2\mass)
Nun setzt man diese Werte in die obrige Formel ein,nun ergibt sich: BlitzBasic: [AUSKLAPPEN] optimisedP# = (2.0 * (a1#-a2#)) / (Ball_mass + wall_mass)
Diese 2.0 soll wahrscheinlich die Masse darstellen,weiß aber nicht wieso er diese auf 2 setzt,aber ich glaub schon wieso: Bei diesem Billiardbeispiel sind die ball massen alle gleich,also braucht er nur noch die geschwindigkeiten der Bälle die aufeinander prallen subtrahieren und das Ergebnis mal 2 nehmen. Am ende dann,zieht er V' dann von dem Vektor der Bälle ab,den sie vor dem Aufprall gehabt hatten: BlitzBasic: [AUSKLAPPEN]
Hoffe ich konnte dir helfen. |
||
Asus F53z
Das Leben ist eine reine Konkatenation... |
- Zuletzt bearbeitet von rambo256 am So, Dez 26, 2004 19:55, insgesamt einmal bearbeitet
Gast |
![]() Antworten mit Zitat |
|
---|---|---|
Genau stimmt.
Gantenberg lässt grüssen... |
||
![]() |
Markus2 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die 2 ist glaube ich da um den Vector zu spiegeln | ||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group