Winkel und Kräfte berechnung bei bewegten Objecten

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

Bob

Betreff: Winkel und Kräfte berechnung bei bewegten Objecten

BeitragMo, Jul 19, 2004 10:55
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jul 19, 2004 18:48
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDi, Jul 20, 2004 7:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Thanks.
Ich werd's mir mal reinziehen und studieren.

Bob

BeitragDo, Jul 22, 2004 16:08
Antworten mit Zitat
Benutzer-Profile anzeigen
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. Smile

Bob

Markus2

BeitragDo, Jul 22, 2004 18:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Jo,
aber eigentlich solltest du Joseph 'Phish' Humfrey danken Wink

Travis

BeitragSa, Dez 11, 2004 3:16
Antworten mit Zitat
Benutzer-Profile anzeigen
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. Idea

Ich habe allerdings massive Probleme, die Funktionsweise der Kollisionsabfrage und der Berechnung der neuen Bewegungsrichtungen zu verstehen.

BlitzBasic: [AUSKLAPPEN]

;------------------------------------------
;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
;------------------------------------------
;------------------------------------------


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
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)


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. Wink
www.funforge.org

Ich hasse WASD-Steuerung.

Man kann alles sagen, man muss es nur vernünftig begründen können.

rambo256

BeitragSa, Dez 18, 2004 13:53
Antworten mit Zitat
Benutzer-Profile anzeigen
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]

c\dx = c\dx - (optimisedP*c2\mass*nX)
c\dy = c\dy - (optimisedP*c2\mass*nY)



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

BeitragSo, Dez 26, 2004 19:52
Antworten mit Zitat
Genau stimmt.

Gantenberg lässt grüssen...

Markus2

BeitragDi, Dez 28, 2004 20:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Die 2 ist glaube ich da um den Vector zu spiegeln

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group