我正在进行重力/太阳系模拟,当模拟运行时,我只得到大约5 fps。这是我的代码的相关部分:
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
最初我在do ...循环中有很大一部分代码并且帧率很好,但是在循环运行时我无法与任何控件交互。如上所示,我可以与控件进行交互,但帧速率非常不稳定。任何帮助将不胜感激。
答案 0 :(得分:1)
从Paint中调用Refresh非常奇怪。一个可能的性能问题是,这会强制整个表单重新绘制,包括背景。我会建议两件事:
创建一个计时器对象,并从Timer_Tick事件中执行计算和更新。
然后从子位置()移除Me.Refresh命令,以便position()和distance()只进行计算。在Timer_Tick的开头和结束处添加对Me.Invalidate()的调用,将包含地球位置的矩形传递给它。这将仅强制重新绘制旧位置和新位置,并且不会重新绘制大量未更改的背景。那么你的Paint方法可能只是2个FillEllipse行。