Physik-Simulation
Zum Code
Das hier ist mal eine komplexere Simulation, dabei werden nur elektronische Kräfte und die Gravitationskräfte beachtet, letztere standardmäßig nur zwischen den einzelnen Objekten. Auf Wunsch kann man die Erdgravitation (Erdoberfläche) anschalten. Auch alle Kräfte können als Kraftlinien eingezeichnet werden.

Zwei Modi sind möglich: Realtime und normale Berechnungen. Beim Realtime-Modus wird die Zeit von der letzten Simulation an gemessen. Beim normalen Modus beträgt die Zeit immer "dt" siehe die entsprechende Textbox. Um das ganze zu beschleunigen, gibt "n" (andere Textbox) an, wie oft dargestellt werden soll. Bei n=50 wird z.B. jede 50. Berechnung dargestellt.

Beide Berechnungen sind jedoch nicht exakt, egal wie klein die Zeitspanne zwischen den Berechnungen ist, es gibt immer Fehler. Diese sieht man vor allem in der Kreisbahn von Objekten -> dafür gibt es die Option "Cheat", wodurch die Formel s=1/2*a*t^2 angepasst wird zu s=1*a*t^2. Dadurch werden gerade Beschleunigen zu groß berechnet, jedoch klappt die Kreisbahn wieder.

Ganz rechts wird die Bahn der Objekte aufgezeichnet, in der Titelleiste steht die momentane Frameleistung.

Die meisten Buttons fügen Objekte in den Worldspace ein, manche mit negativen Ladungen, manche mit positiven, manchmal Fixsterne, je nachdem. Gerechnet wird immer in den korrekten physikalischen Masseinheiten, also Meter, Newton etc. Zudem sind einige unfertige Spielereien dabei, wie z.B. der Versuch, Kraftfelder einzeichnen zu lassen.

Viel Spaß damit, spielt einfach mal ein wenig rum und wenn ihr es hinkriegt, Kraftfelder einzuzeichnen, mailt mir :D

History
26.12.2002 Online gestellt

Autor: Dominik Auras <Dominik_auf_vbinside.de>

Code aus Form1.frm
Option Explicit

Private Sub Command1_Click()
Dim Objekt As Objekt, Kraftvektor As Kraftvektor

Randomize Timer
ReDim Objekt.Kräfte(0)
Objekt.Masse = 3000000000000#
'kg
Objekt.Position.x = Form1.Picture1.ScaleWidth / 2 / PixelPerMeter
'm
Objekt.Position.y = Form1.Picture1.ScaleHeight / 2 / PixelPerMeter
Objekt.Grösse.width = 1#
'm
Objekt.Grösse.height = 1#
Objekt.Ladung = Elementarladung
Objekt.Fixed = True

AddObjekt Objekt, Worldspace

Call Command2_Click

'QueryPerformanceCounter last
'Timer1.Enabled = True
'Do: DoEvents: Schleife: Loop
End Sub

Private Sub Command2_Click()
Dim Objekt As Objekt

Const r = 3
ReDim Objekt.Kräfte(0)
Objekt.Masse = 100
'kg
Objekt.Position.x = Form1.Picture1.ScaleWidth / 2 / _
PixelPerMeter + r
'm
Objekt.Position.y = Form1.Picture1.ScaleHeight / 2 / PixelPerMeter
' - 6
Objekt.Grösse.width = 1#
'm
Objekt.Grösse.height = 1#
Objekt.Ladung = 0.001
'C

Objekt.Geschwindigkeit.y = 8

AddObjekt Objekt, Worldspace
End Sub

Private Sub Command3_Click()
Dim Objekt As Objekt, Kraftvektor As Kraftvektor

ReDim Objekt.Kräfte(0)
Objekt.Masse = 10
'kg
Objekt.Position.x = Form1.Picture1.ScaleWidth / 2 / _
PixelPerMeter + 15
'm
Objekt.Position.y = Form1.Picture1.ScaleHeight / 2 / PixelPerMeter
Objekt.Grösse.width = 1
'm
Objekt.Grösse.height = 1
Objekt.Ladung = 0.002
'C

Objekt.Geschwindigkeit.y = 6

AddObjekt Objekt, Worldspace
End Sub

Sub Schleife()
Dim Objekt As Objekt, x As Long, y As Long, height As Long, _
width As Long
Dim Farbe As Long, KraftX As Double, KraftY As Double, _
Kraftvektor As Kraftvektor
Dim i As Long, n As Long, d As Long

Static h

Const c = 10

'Schritt 1
KräfteBerechnen

'Schritt 2
ObjekteBewegen

'Schritt 3
KollisionenErkennen

d = Val(Text1.Text)
If d <= 0 Then
d = 500
End If

h = h + 1

If h Mod d <> 0 Then
Goto novid
End If

h = 0

'Schritt 4 - Zeichen
Picture1.Cls
'Picture1.PaintPicture Picture2.Image, 0, 0

For i = 1 To UBound(Worldspace)
Objekt = Worldspace(i)

x = Objekt.Position.x * PixelPerMeter
y = Form1.Picture1.ScaleHeight - Objekt.Position.y * PixelPerMeter
width = Objekt.Grösse.width * PixelPerMeter
height = Objekt.Grösse.height * PixelPerMeter

If Objekt.Masse < 10000 Then
Farbe = RGB(0, 0, 0)

If Objekt.Ladung < 0 Then
Farbe = RGB(0, 0, 200)
ElseIf Objekt.Ladung > 0 Then
Farbe = RGB(200, 0, 0)
End If

If Objekt.Crashed Then
Farbe = RGB(120, 0, 0)
End If
Else
Farbe = RGB(255, 0, 0)
End If

Picture1.Line (x - width / 2, y - height / 2)-(x + width / _
2, y + height / 2), Farbe, BF
Picture2.Line (Objekt.LastPos.x * PixelPerMeter, _
Form1.Picture1.ScaleHeight - Objekt.LastPos.y * _
PixelPerMeter)-(x, y), Objekt.TraceFarbe

Objekt.LastPos = Objekt.Position

If Check3.Value <> vbChecked Then
Goto weiter
End If

For n = 1 To UBound(Objekt.DisplayVektoren)
Kraftvektor = Objekt.DisplayVektoren(n)

KraftX = Kraftvektor.x / Objekt.Masse * c
KraftY = Kraftvektor.y / Objekt.Masse * c

Picture1.Line (x, y)-(x + KraftX, y - KraftY), RGB(0, 0, 255)
Next n

KraftX = Objekt.ResultierendeKraft.x / Objekt.Masse * c
KraftY = Objekt.ResultierendeKraft.y / Objekt.Masse * c
Picture1.Line (x, y)-(x + KraftX, y - KraftY), RGB(255, 0, 0)

KraftX = Objekt.Geschwindigkeit.x / Objekt.Masse * c * 10
KraftY = Objekt.Geschwindigkeit.y / Objekt.Masse * c * 10
Picture1.Line (x, y)-(x + KraftX, y - KraftY), RGB(0, 255, 0)

weiter:
Worldspace(i) = Objekt
Next i
novid:
End Sub

Private Sub Command4_Click()
Dim Objekt As Objekt, Kraftvektor As Kraftvektor
Const d = 5

Randomize Timer

ReDim Objekt.Kräfte(0)
Objekt.Masse = 3000000000000#
'kg
Objekt.Position.x = Form1.Picture1.ScaleWidth / 2 / _
PixelPerMeter - d
'm
Objekt.Position.y = Form1.Picture1.ScaleHeight / 2 / PixelPerMeter
Objekt.Grösse.width = 1
'm
Objekt.Grösse.height = 1
Objekt.Ladung = Elementarladung
Objekt.Fixed = True

AddObjekt Objekt, Worldspace

ReDim Objekt.Kräfte(0)
Objekt.Masse = 3000000000000#
'kg
Objekt.Position.x = Form1.Picture1.ScaleWidth / 2 / _
PixelPerMeter + d
'm
Objekt.Position.y = Form1.Picture1.ScaleHeight / 2 / PixelPerMeter
Objekt.Grösse.width = 1
'm
Objekt.Grösse.height = 1
Objekt.Ladung = Elementarladung
Objekt.Fixed = True

AddObjekt Objekt, Worldspace

Call Command5_Click

'QueryPerformanceCounter last
'Timer1.Enabled = True
'Do: DoEvents: Schleife: Loop
End Sub

Private Sub Command5_Click()
Dim Objekt As Objekt, Kraftvektor As Kraftvektor

ReDim Objekt.Kräfte(0)
Objekt.Masse = 10
'kg
Objekt.Position.x = Form1.Picture1.ScaleWidth / 2 / PixelPerMeter
' + 3 'm
Objekt.Position.y = Form1.Picture1.ScaleHeight / 2 / _
PixelPerMeter - 8
Objekt.Grösse.width = 1
'm
Objekt.Grösse.height = 1
Objekt.Ladung = 0.00001
'C

Objekt.Geschwindigkeit.y = 0

AddObjekt Objekt, Worldspace
End Sub

Private Sub Command6_Click()
Dim Objekt As Objekt, v As Double

Const r = 3
ReDim Objekt.Kräfte(0)
Objekt.Masse = 100
'kg
Objekt.Position.x = Form1.Picture1.ScaleWidth / 2 / _
PixelPerMeter + r
'm
Objekt.Position.y = Form1.Picture1.ScaleHeight / 2 / PixelPerMeter
' - 6
Objekt.Grösse.width = 1#
'm
Objekt.Grösse.height = 1#
Objekt.Ladung = -0.001
'C

Objekt.Geschwindigkeit.y = 0

AddObjekt Objekt, Worldspace
End Sub

Private Sub Command7_Click()
Picture2.Cls
End Sub

Private Sub Form_Load()
QueryPerformanceFrequency Freq
PixelPerMeter = 20

Randomize Timer

ReDim Worldspace(0)

Picture2.Cls
Picture1.Cls

Picture2.Picture = Picture2.Image

QueryPerformanceCounter last
Me.Show
Do: Schleife: DoEvents: Loop
End Sub

Private Sub Form_Unload(Cancel As Integer)
End
End Sub

Private Sub Timer1_Timer()
Schleife
End Sub