Ich mache eine Gravitation/Sonnensystem Simulation und wenn die Simulation läuft bekomme ich nur 5 fps. Hier ist der relevante Teil meines Code:Eine sehr schlechte Framerate in der VB.net-Physiksimulation. Irgendwelche Vorschläge?
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles picSpace.Paint
earth.displayX = Math.Round(earth.positionX)
earth.displayY = Math.Round(earth.positionY)
e.Graphics.FillEllipse(Brushes.Blue, earth.displayX - 5, earth.displayY - 5, 10, 10)
e.Graphics.FillEllipse(Brushes.Yellow, sunX - 10, sunY - 10, 20, 20)
distance()
position()
End Sub
Sub distance()
dX = sunX - earth.positionX
dY = sunY - earth.positionY
If (earth.positionX >= sunX) And (earth.positionY <= sunY) Then
dX *= -1
Else
If (earth.positionX >= sunX) And (earth.positionY >= sunY) Then
dX *= -1
dY *= -1
Else
If (earth.positionX <= sunX) And (earth.positionY >= sunY) Then
dY *= -1
Else
If (earth.positionX <= sunX) And (earth.positionY <= sunY) Then
'do nothing
End If
End If
End If
End If
d = Math.Sqrt((((dY) * 1000000)^2) + (((dX) * 1000000)^2))
d = d * 1000
End Sub
Sub position()
If first = False Then
earth.positionX += ((((earth.oldVelocityX + earth.velocityX)/2) * simulationSpeed)/1000000000)
earth.positionY += ((((earth.oldVelocityY + earth.velocityY)/2) * simulationSpeed)/1000000000)
orbit(0, counter) = earth.positionX
orbit(1, counter) = earth.positionY
counter += 1
ReDim Preserve orbit(1, counter)
lblPositionX.Text = "X: " & Math.Truncate(earth.positionX)
lblPositionY.Text = "Y: " & Math.Truncate(earth.positionY)
End If
F = (earth.mass * sunMass * G)/(d^2)
theta = Math.Atan(dX/dY)
If (earth.positionX >= sunX) And (earth.positionY <= sunY) Then
earth.forceX = F * Math.Sin(theta) * -1
earth.forceY = F * Math.Cos(theta)
Else
If (earth.positionX >= sunX) And (earth.positionY >= sunY) Then
earth.forceX = F * Math.Sin(theta) * -1
earth.forceY = F * Math.Cos(theta) * -1
Else
If (earth.positionX <= sunX) And (earth.positionY >= sunY) Then
earth.forceX = F * Math.Sin(theta)
earth.forceY = F * Math.Cos(theta) * -1
Else
If (earth.positionX <= sunX) And (earth.positionY <= sunY) Then
earth.forceX = F * Math.Sin(theta)
earth.forceY = F * Math.Cos(theta)
End If
End If
End If
End If
a = F/earth.mass
earth.accelerationX = earth.forceX/earth.mass
earth.accelerationY = earth.forceY/earth.mass
earth.oldVelocityX = earth.velocityX
earth.oldVelocityY = earth.velocityY
earth.velocityX = earth.oldVelocityX + (earth.accelerationX * simulationSpeed)
earth.velocityY = earth.oldVelocityY + (earth.accelerationY * simulationSpeed)
first = False
Me.Refresh()
End Sub
Ursprünglich hatte ich einen großen Teil des Codes in einem Do ... Loop und die Framerate war in Ordnung, aber ich konnte nicht mit irgendwelchen Kontrollen interagieren, während die Schleife war Laufen. Wenn ich es wie oben gezeigt mache, kann ich mit den Steuerelementen interagieren, aber die Framerate ist sehr abgehackt. Jede Hilfe würde sehr geschätzt werden.
Nicht im Zusammenhang mit Ihrem Leistungsproblem, aber als allgemeine .NET-Empfehlung bevorzugen Sie immer das Überschreiben der Ereignisbehandlung. Überschreiben Sie in diesem Fall die Methode 'OnPaint', anstatt das Ereignis 'Paint' zu verarbeiten: http://StackOverflow.com/a/3670912/172769 –
Ich würde auch sagen, dass die Handhabung in 'Form.Paint' nicht geht sehr deterministisch sein, wie es zu oft (oder nicht genug) genannt werden kann. Ich würde empfehlen, eine Timer basierte Berechnung zu versuchen. Ich meine, Sie können immer noch die Formen in Paint zeichnen, aber lassen Sie den Kalkül Teil, vielleicht auf einem Hintergrund Arbeiter ausgelöst jede Sekunde (oder welche Zeitbasis Sie für Ihre Simulation am besten halten) –