Проблема заключается в этой строке
For x As Integer = 0 To totalTime Step 0.01
x - это целое число, и когда вы добавляете к нему 0,01, оно никогда не будет увеличиваться. Сделай xa Double. На самом деле, вы можете избавить себя от головной боли, позволив компилятору определить правильный тип
For x = 0 To totalTime Step 0.01 ' it is now Double
, а также добавив Option Strict On
в верхней части вашего файла кода, в любом случае проблема для вас найдется
For x As Integer = 0 To totalTime Step 0.01
Option Strict On запрещает неявное преобразование из 'Double' в 'Integer'
В другом ответе и комментариях предлагается отладить код. Конечно, отладка помогла бы вам здесь. Если бы я был тобой, я бы позволил ему работать, поставил точку останова в цикле For и проверил, что происходит. Было бы очевидно, что переменная цикла не увеличивается.
Согласно другому ответу, вы можете добавить Console.WriteLine в цикл. Эта строка будет хорошо работать внутри цикла
Console.WriteLine($"Inside For loop, x:{x}, xPos:{xPos}, yPos:{yPos}")
, что будет означать
Внутри цикла For, x: 0, xPos: 0, yPos: 10
Inside Forloop, x: 0, xPos: 0, yPos: 10
Inside For loop, x: 0, xPos: 0, yPos: 10
Inside For loop, x: 0, xPos: 0, yPos: 10
Внутри цикла For, x: 0, xPos: 0, yPos: 10
Там, где можно ожидать изменения значений. Они делают, когда это цикл Double
Inside For, x: 0, xPos: 0, yPos: 10
Inside For loop, x: 0.01, xPos: 0.0707106781186548, yPos: 11.6202267316012
Внутри для цикла, x: 0,02, xPos: 0,14142135623731, yPos: 12.3327679741871
Внутри для цикла, x: 0,03, xPos: 0.212132034355964, yPos: 12.8959725661313
Inside для цикла, x: 0,04, xPos: 0,246284: 13.3818748194396
Я все еще не думаю, что это завершено.
Нет причин выполнять весь цикл в пользовательском интерфейсе. Так что отделите вашу обработку и пользовательский интерфейс. Есть много способов достичь этого. Один использует Async / Await , и я считаю это самым простым способом. Поймите, что когда вы работаете за пределами пользовательского интерфейса, вам нужно будет вызывать обратные вызовы пользовательского интерфейса, чтобы делать там какие-либо обновления.
Самый большой удар по производительности, который вы создаете, - это добавление аннотации к диаграмме для каждого увеличения с 0,01. во время. Это действительно необходимо? Без добавления аннотаций построение происходит очень быстро. С аннотациями он быстро замедляется до ползания.
Вам нужно продолжать обработку, когда y достигнет нуля? Я добавил логику для выхода из цикла, как только это произойдет.
Обратите внимание, что Await отправит код с интерфейса, поэтому ваш интерфейс будет интерактивным во время работы. Вот код, который демонстрирует это. Обратите внимание, что аннотации добавляются каждые 0,1 секунды вместо 0,01. Они эффективно уничтожены. Вы можете дурачиться с ним, чтобы заставить его работать так, как вам нужно.
Private gConstant As Double = 9.8
Private totalTime As Double
Private velocity As Double
Private angle As Double
Private elevation As Double
Private heightOfProjectile As Double
Private flightRange As Double
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
totalTime = 100
velocity = 100
angle = Math.PI / 4
elevation = 100
heightOfProjectile = 10
flightRange = 10
Chart1.ChartAreas(0).AxisX.Minimum = 0
Chart1.Series("Projection").ChartType = SeriesChartType.FastLine
Await Task.Factory.StartNew(AddressOf getPoints)
End Sub
Private Sub getPoints()
For x As Double = 0 To totalTime Step 0.01
Dim xPos As Double = findXLocation(velocity, angle, x)
Dim yPos As Double = findYLocation(velocity, angle, x, elevation, totalTime, heightOfProjectile, flightRange)
Dim l = x
Chart1.Invoke(
Sub()
Chart1.Series("Projection").Points.AddXY(xPos, yPos)
If CInt(100 * l) Mod 10 = 0 Then Chart1.Annotations.Add(New CalloutAnnotation())
End Sub)
Console.WriteLine($"Inside For loop, x:{x}, xPos:{xPos}, yPos:{yPos}")
If yPos = 0 Then Exit For
Next
End Sub
Public Function findYLocation(ByVal velocity As Double, ByVal angle As Double, ByVal time As Double, ByVal elevation As Double, ByVal totalTime As Double, ByVal heightOfProjectile As Double, ByVal flightRange As Double) As Double
Return Math.Max(0, -0.5 * gConstant * sq(time) + findVerticalVelocity(velocity, angle) * time + elevation)
End Function
Private Function sq(value As Double) As Double
Return value ^ 2
End Function
Public Function findXLocation(ByVal velocity As Double, ByVal angle As Double, ByVal time As Double) As Double
Return Math.Max(0, findHorizontalVelocity(velocity, angle) * time)
End Function
Private Function findVerticalVelocity(velocity As Double, angle As Double) As Double
Return Math.Sin(angle) * velocity
End Function
Private Function findHorizontalVelocity(velocity As Double, angle As Double) As Double
Return Math.Cos(angle) * velocity
End Function