Ideal Elastischer Stoß - Geht nicht

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

ToeB

Betreff: Ideal Elastischer Stoß - Geht nicht

BeitragDi, Mai 24, 2011 14:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo !

Ich habe in Physik von meinem Lehrer (Welcher auch mein Info-Lehrer ist), eine Aufgabe bekommen, ein Programm in BlitzMax zu schreiben welches den Idealen Elatischen Stoß Simuliert und somit Veranschaulicht. Dazu habe ich mir gedacht, kann ich Folgende Formel nehmen und damit die einzellnen Vektoren ausrechnen... Geht aber iwie nicht :Zitat:
v1_nach = ((m1-m2)/(m1+m2))*v1_vor + ((2*m2)/(m1+m2))*v2_vor
v2_nach = ((m2-m1)/(m1+m2))*v2_vor + ((2*m1)/(m1+m2))*v1_vor


Die Geschwindigkeits-Beträge der Vektoren werden damit auch richtig errechnet, nicht allerdings die Richtung. Könnt ihr mir da Villeicht weiterhelfen ? Hier mein Code bisher (Kollisions + Geschwindigkeits berechnung in der Methode TBall.UpdateBallKollision :

(Linke Maustaste drücken und gedrückt halten -> "Ball" hinzufügen, rechte Maustaste auf einen Ball drücken und gedrückt halten -> Ball bewegen)

BlitzMax: [AUSKLAPPEN]
SuperStrict 

Type TSystem
Global BasicSystem:TSystem = New TSystem

Field resX:Int, resY:Int
Field grav:Float[2], fric:Float
Field createBall:TBall, createBallState:Byte
Field moveBall:TBall, moveBallState:Byte
Field Mx:Float, My:Float

Field timer:TTimer

Method New( )
End Method

Method Create:TSystem( gravX:Float, gravY:Float, fric:Float=1.0, resX:Int=800, resY:Int=600, timerFreq:Int=60 )
EndGraphics( )
Graphics( resX, resY, 0, 60 )
Self.resX = resX
Self.resY = resY
Self.grav[0] = gravX
Self.grav[1] = gravY
Self.fric = fric
Self.timer = CreateTimer( timerFreq )
Return Self
End Method

Method UpdateBalls( )
Mx = MouseX( )
My = MouseY( )
If MouseHit( 1 ) And createBallState = 0 And moveBallState = 0 Then
createBallState = 1
createBall = (New TBall).Create( mX, mY, 0, 0, 0, False, False )
EndIf
If MouseHit( 2 ) And moveBallState = 0 And createBallState = 0 Then
Local tmpGet:Byte = 0
For moveBall = EachIn TBall.Liste
Local tmpAbsX:Float = Mx - moveBall.position[0]
Local tmpAbsY:Float = My - moveBall.position[1]
Local tmpAbs:Float = Sqr( tmpAbsX*tmpAbsX + tmpAbsY*tmpAbsY )
If tmpAbs <= moveBall.radius Then
tmpGet = 1
Exit
EndIf
Next
If tmpGet = 1 Then
moveBallState = 1
moveBall.kollision = False
moveBall.Physik = False
EndIf
EndIf
If createBallState = 1 Then
Local tmpAbsX:Float = Mx - createBall.position[0]
Local tmpAbsY:Float = My - createBall.position[1]
Local tmpAbsW:Float = ATan2( tmpAbsY, tmpAbsX )
Local tmpAbsA:Float = Sqr( tmpAbsX * tmpAbsX + tmpAbsY * tmpAbsY )
createBall.radius = tmpAbsA
createBall.winkel = tmpAbsW
If MouseDown( 1 ) = 0 Then
createBall.kollision = True
createBall.Physik = True
createBall.masse = createBall.radius / 10.0
createBall = Null
createBallState = 0
EndIf
EndIf
If moveBallState = 1 Then
If MouseDown( 2 ) = 0 Then
Local tmpAbsX:Float = Mx - moveBall.position[0]
Local tmpAbsY:Float = My - moveBall.position[1]
Local tmpAbsW:Float = ATan2( tmpAbsY, tmpAbsX )
Local tmpAbsA:Float = ( Sqr( tmpAbsX * tmpAbsX + tmpAbsY * tmpAbsY ) ) / 50.0
moveBall.geschwindigkeit[0] = Cos( tmpAbsW ) * tmpAbsA
moveBall.geschwindigkeit[1] = Sin( tmpAbsW ) * tmpAbsA
moveBall.kollision = True
moveBall.Physik = True
moveBall = Null
moveBallState = 0
EndIf
EndIf
If KeyHit( KEY_1 ) Then grav[1] = 0.0981
If KeyHit( KEY_2 ) Then grav[1] = 0.0
For Local tmpBall:TBall = EachIn TBall.Liste

tmpBall.UpdateMoving( )

If tmpBall.kollision = True Then
tmpBall.UpdateLineKollision( )

Local listLink:TLink = tmpBall.ListLink.NextLink( )
While listLink <> Null
Local tmp:TBall = TBall( listLink.Value( ) )

tmpBall.UpdateBallKollision( tmp )

listLink = listLink.NextLink( )
Wend

EndIf
Next
End Method

Method LimitFrames( )
WaitTimer( Self.Timer )
End Method

Method Draw( )
SetLineWidth( 1 )
SetColor( 64, 64, 64 )
SetAlpha( 0.2 )
SetBlend( ALPHABLEND )
For Local tmpX:Float = 0 To resX Step 20
DrawLine( tmpX, 0, tmpX, resY )
Next
For Local tmpY:Float = 0 To resY Step 20
DrawLine( 0, tmpY, resX, tmpY )
Next
For Local tmpBall:TBall = EachIn TBall.Liste
tmpBall.Draw( )
Next
If moveBallState = 1 Then
SetColor( 64, 64, 255 )
DrawLine( moveBall.position[0], moveBall.position[1], Mx, My )
EndIf
End Method
End Type

Type TBall
Global Liste:TList = CreateList( )

Field ListLink:TLink
Field position:Float[2], position_neu:Float[2]
Field geschwindigkeit:Float[2]
Field radius:Float
Field winkel:Float
Field masse:Float
Field kollision:Byte, physik:Byte

Method Create:TBall( posX:Float, posY:Float, radius:Float, winkel:Float, masse:Float, kollision:Byte=True, physik:Byte=True )
Self.position[0] = posX
Self.position[1] = posY
Self.radius = radius
Self.winkel = winkel
Self.kollision = kollision
Self.physik = physik
Self.masse = masse
Return Self
End Method

Method UpdateMoving:Byte( )
If Self.Physik = False Then Return 0
Self.position[0] :+ Self.geschwindigkeit[0]
Self.position[1] :+ Self.geschwindigkeit[1]
Self.geschwindigkeit[0] :+ TSystem.BasicSystem.grav[0]
Self.geschwindigkeit[1] :+ TSystem.BasicSystem.grav[1]
Self.geschwindigkeit[0] :* TSystem.BasicSystem.fric
Self.geschwindigkeit[1] :* TSystem.BasicSystem.fric
End Method


Method UpdateBallKollision:Byte( tmpBall:TBall )
If Self.kollision = False Or tmpBall.kollision = False Then Return 0

Local tmpAbsX:Float = tmpBall.position[0] - Self.position[0]
Local tmpAbsY:Float = tmpBall.position[1] - Self.position[1]

Local tmpAbs:Float = Sqr( tmpAbsX*tmpAbsX + tmpAbsY*tmpAbsY )
Local tmpRad:Float = tmpBall.radius + Self.radius

If tmpAbs <= tmpRad Then

Local tmpNormX:Float = tmpAbsX / tmpAbs
Local tmpNormY:Float = tmpAbsY / tmpAbs

Local tmpAb:Float = (tmpRad-tmpAbs) * 0.5

Self.position[0] :- tmpNormX * tmpAb
Self.position[1] :- tmpNormY * tmpAb
tmpBall.position[0] :+ tmpNormX * tmpAb
tmpBall.position[1] :+ tmpNormY * tmpAb

Local tmpMasse:Float = Self.masse + tmpBall.masse
Local tmpV1_Vor:Float[2]
Local tmpV2_Vor:Float[2]

tmpV1_Vor[0] = Self.geschwindigkeit[0]
tmpV1_Vor[1] = Self.geschwindigkeit[1]
tmpV2_Vor[0] = tmpBall.geschwindigkeit[0]
tmpV2_Vor[1] = tmpBall.geschwindigkeit[1]

Self.geschwindigkeit[0]=((Self.masse-tmpBall.masse)/tmpMasse)*tmpV1_Vor[0] + ((2*tmpBall.Masse)/tmpMasse)*tmpV2_Vor[0]
Self.geschwindigkeit[1]=((Self.masse-tmpBall.masse)/tmpMasse)*tmpV1_Vor[1] + ((2*tmpBall.Masse)/tmpMasse)*tmpV2_Vor[1]
tmpBall.geschwindigkeit[0]=((tmpBall.masse-Self.masse)/tmpMasse)*tmpV2_Vor[0] + ((2*Self.Masse)/tmpMasse)*tmpV1_Vor[0]
tmpBall.geschwindigkeit[1]=((tmpBall.masse-Self.masse)/tmpMasse)*tmpV2_Vor[1] + ((2*Self.Masse)/tmpMasse)*tmpV1_Vor[1]

EndIf

End Method


Method UpdateLineKollision( )
If Self.position[0]+Self.radius > TSystem.BasicSystem.resX Then
Self.position[0] = TSystem.BasicSystem.resX-Self.radius
Self.geschwindigkeit[0] = Self.geschwindigkeit[0] * -1
EndIf
If Self.position[1]+Self.radius > TSystem.BasicSystem.resY Then
Self.position[1] = TSystem.BasicSystem.resY-Self.radius
Self.geschwindigkeit[1] = Self.geschwindigkeit[1] * -1
EndIf
If Self.position[0]-Self.radius < 0 Then
Self.position[0] = Self.radius
Self.geschwindigkeit[0] = Self.geschwindigkeit[0] * -1
EndIf
If Self.position[1]-Self.radius < 0 Then
Self.position[1] = Self.radius
Self.geschwindigkeit[1] = Self.geschwindigkeit[1] * -1
EndIf
End Method

Method Draw( )
Local pos:Float[2]
SetBlend( ALPHABLEND )
SetAlpha( 0.2 )
SetColor( 255, 64, 64 )
DrawOval( Self.position[0]-Self.radius, Self.position[1]-Self.radius, Self.radius*2, Self.radius*2 )
SetColor( 255, 0, 0 )
SetLineWidth( 5 )
SetAlpha( 1 )
DrawOval_Ex( Self.position[0], Self.position[1], Self.radius, 10 )
SetColor( 64, 255, 64 )
pos[0] = Self.position[0]+ Cos( Self.winkel )*Self.radius
pos[1] = Self.position[1]+ Sin( Self.winkel )*Self.radius
DrawLine( Self.position[0], Self.position[1], pos[0], pos[1] )
End Method

Method New( )
ListLink = Liste.AddLast( Self )
End Method

Method Remove( )
ListLink.Remove( )
End Method
End Type



TSystem.BasicSystem.Create( 0.0, 0.0, 1, 800, 600, 60 )

Repeat

TSystem.BasicSystem.UpdateBalls( )

Cls

TSystem.BasicSystem.Draw( )

Flip 0

TSystem.BasicSystem.LimitFrames( )

Until KeyHit( KEY_ESCAPE ) Or AppTerminate( )
End


Function MinMax( Value:Float Var, min_value:Float, max_value:Float )
Value = Min( Max( Value, min_value ), max_value )
End Function

Function DrawOval_Ex( tmpMidX:Float, tmpMidY:Float, tmpRadius:Float, tmpDetail:Float=1.0 )
Local tmpAngle:Float
Local tmpStartX:Float, tmpEndX:Float
Local tmpStartY:Float, tmpEndY:Float

tmpStartX = tmpMidX + tmpRadius
tmpStartY = tmpMidY

For tmpAngle = 1 To 360.0 / tmpDetail
tmpEndX = tmpMidX + Cos( tmpAngle*tmpDetail ) * tmpRadius
tmpEndY = tmpMidY + Sin( tmpAngle*tmpDetail ) * tmpRadius

DrawLine( tmpStartX, tmpStartY, tmpEndX, tmpEndY )

tmpStartX = tmpEndX
tmpStartY = tmpEndY
Next

End Function


Function TurnVector( vx:Float Var, vy:Float Var, a:Float )

Local tmpAbs:Float = Sqr( vx*vx + vy*vy )
Local tmpA:Float = ATan2( vy, vx ) + a

vx = Cos( tmpA ) * tmpAbs
vy = Sin( tmpA ) * tmpAbs

End Function

Function AbsAngle:Float(a_pos:Float, a_ziel:Float)

Local a_tmp:Float = ( ( a_ziel Mod 360 ) - ( a_pos Mod 360 ) ) Mod 360

If a_tmp < -180
a_tmp = a_tmp + 360
ElseIf a_tmp > 180
a_tmp = a_tmp - 360
EndIf

Return a_tmp

End Function


Ich Hoffe ihr könnt mir Helfen Confused


Edit : Oder an die, die mit dem Code nicht klar kommen: Wie kann ich im Allgemeinen die Vektoren der beiden Geschwindigkeiten NACH dem Stoß am besten berechnen (sodass sowohl Betrag als auch Richtung stimmen) ?

mfg ToeB
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!

mpmxyz

BeitragDi, Mai 24, 2011 17:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Du musst die Geschwindigkeiten in einen Anteil, der durch die Kollisionsfläche geht, und einen Anteil, der tangential dazu verläuft, aufteilen.
Der Anteil, der durch die Kollisionsfläche geht, wird wie beim eindimensionalen elastischen Stoß verrechnet. Der andere Teil bleibt beim entsprechenden Körper erhalten und wird zum Ergebnis vom anderen Teil hinzuaddiert.
Meine Quelle: http://en.wikipedia.org/wiki/E...imensional
Zum Aufspalten kannst du das Skalarprodukt mit einem Einheitsvektor verwenden.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

ToeB

BeitragDi, Mai 24, 2011 17:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Okay, danke erstmal bis hierhin.

Unten kommt ja diese Formel raus :
user posted image
Was ist diese komische durchgestrichene 0 nochmal ? Mit fällt es grad iwie nicht mehr ein ...

Und : Ist das die Entgültige Formel (wegen dem Cos) oder wie darf ich das verstehen ?


mfg ToeB
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!

mpmxyz

BeitragDi, Mai 24, 2011 17:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist die Formel bei einem ruhigen und einem bewegten Objekt.
-> Für deinen Fall ist diese ungeeignet.
Θ ist ein Theta. (eine Winkelangabe)
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

ToeB

BeitragDi, Mai 24, 2011 18:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Sry aber ich blick da grad wirklich net durch... Wo krig ich denn die Formel für 2 sich bewegende Körper her ? Oder bzw. wie leite ich diese von der hier ab ? Kann ich das überhaubt ?


mfg ToeB
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!

ToeB

BeitragDi, Mai 24, 2011 19:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Sry für Doppelpost aber ich glaube ich habs verstanden Very Happy

Ich muss also, wenn die beiden Kollidieren, einmal den Vektor ausrechnen (Mit hilfe des Scalarproduktes), welcher jeweils in die Richtung des anderen Balls zeigt, und dann jeweils den Vector, die im 90° Winkel dazu stehen (von den Geschwindigkeits vektoren). Dann mit der Formel die ersten Vektoren errechnen und die zweiten dazuaddieren, fertig. Oder ?


mfg ToeB
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!

mpmxyz

BeitragDi, Mai 24, 2011 19:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, so in etwa.
Die ersten Vektoren, die jeweils in Richtung der Kugel zeigen, werden miteinander verrechnet.
Die zweiten Vektoren bleiben bei ihrer jeweiligen Kugel und werden zu den jeweiligen Ergebnissen aus dem ersten Teil addiert. (Ich wiederhole es, um Fehler auszuschließen.)
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

ToeB

BeitragDi, Mai 24, 2011 19:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Ah okay super ich habs endlich verstanden super danke Very Happy


mfg ToeB
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group