我有一个方程可以用来查找火炮的炮高,使用范围,初速和高度变化在一个名为Arma 3的游戏中。方程式如下:
g是重力加速度(9.80665),V是初速度,X是范围,Y是高度变化(在我的代码中称为DAlt)。
我正在尝试将其转换为一行代码,以便我可以创建一个程序来根据给定的坐标计算高程。但是我遇到了麻烦。我目前有这个:
If rdoLow.Checked = True Then
Elevation = Math.Atan(((Velocity ^ 2) - (Math.Sqrt((Velocity ^ 4) - (G) * (G * (Range ^ 2) + (2 * DAlt * (Velocity ^ 2)))))) / G * Range)
Else
Elevation = Math.Atan(((Velocity ^ 2) + (Math.Sqrt((Velocity ^ 4) - (G) * (G * (Range ^ 2) + 2 * DAlt * (Velocity ^ 2))))) / G * Range)
End If
哪个不是特别漂亮,但据我所知,它应该有效。然而,当我输入我使用的等式的视频的值时,我得到了不同的答案。所以我的等式肯定有问题。
我已经尝试将它分成各个部分作为单独的变量并计算它们,然后在整个等式中使用这些变量,但仍然没有用,并给了我一个错误的答案。
所以我目前对如何修复它感到茫然,开始怀疑vb处理长方程的方式是否不同或类似。
非常感谢任何帮助。
答案 0 :(得分:2)
您还没有提供任何样本数据,因此我无法验证这是否给出了正确答案,但等式的最后一部分缺少一些括号。
Elevation = Math.Atan(((Velocity ^ 2) + Math.Sqrt((Velocity ^ 4) - (G * ((G * (Range ^ 2)) + (2 * DAlt * (Velocity ^ 2)))))) / (G * Range))
请注意最后G * Range
周围的括号。
乘法和除法具有相同的优先级,因此它们是从左到右进行计算的。请参阅Operator Precedence in Visual Basic。
您将所有内容除以G
,然后将结果乘以Range
,而您需要将G
乘以Range
,然后将所有内容除以结果
您可以在这个简单示例中看到不同之处:
Console.WriteLine(3 / 4 * 5) ' Prints 3.75
Console.WriteLine(3 / (4 * 5)) ' Prints 0.15
答案 1 :(得分:1)
出于好奇,我尝试了这个问题。为了获得测试数据,我找到了这个网站,Range Tables For Mortars。我测试了'82mm迫击炮 - 远',其初始速度为200米/秒。我遇到的一个问题是,我不知道我是否正确地修正了它,方程的第一部分是返回负数......我也解决了±。为了测试我创建了一个带有按钮来执行计算的表单,一个用于输入距离的文本框,以及两个用于显示角度的标签。这就是我想出来的。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'A - launch angle
'Target
' r - range
' y - altitude
'g - gravity 9.80665 m/s^2
'v - launch speed e.g. 50 m/s
'
'
'Formula
'from - https://en.wikipedia.org/wiki/Trajectory_of_a_projectile#Angle_required_to_hit_coordinate_.28x.2Cy.29
'in parts
'parts - px
' p1 = sqrt( v^4 - g * (g * r^2 + 2 * y * v^2) )
' p2 = v^2 ± p1 note plus / minus
' p3 = p2 / g * r
'
' A = arctan(p3)
Dim Ap, Am, r, y As Double
Dim g As Double = 9.80665
Dim v As Double
Dim p1, p2p, p2m, p3p, p3m As Double
If Not Double.TryParse(TextBox1.Text, r) Then Exit Sub
y = 0
v = 200 '82mm Mortar - Far velocity
p1 = v ^ 4 - g * (g * r ^ 2 + 2 * y * v ^ 2)
If p1 < 0 Then
Debug.WriteLine(p1)
p1 = Math.Abs(p1) 'square root does not like negative numbers
End If
p1 = Math.Sqrt(p1)
'plus / minus
p2p = v ^ 2 + p1
p2m = v ^ 2 - p1
p3p = p2p / (g * r)
p3m = p2m / (g * r)
Const radiansToDegrees As Double = 180 / Math.PI
Ap = Math.Atan(p3p) * radiansToDegrees
Am = Math.Atan(p3m) * radiansToDegrees
Label1.Text = Ap.ToString("n3")
Label2.Text = Am.ToString("n3")
End Sub
使用网站验证计算代码是否正确。
在一堆嵌套括号中编写长公式没有任何意义,除非你感到困惑。