2016-03-06 4 views
1

J'ai une équation qui peut être utilisé pour trouver l'élévation des armes à feu pour l'artillerie, en utilisant la gamme, la vitesse initiale et le changement d'altitude dans un jeu appelé Arma 3. L'équation ressemble à ceci: enter image description hereConversion d'une équation au code

Avec g étant l'accélération due à la gravité (9.80665), V étant la vitesse initiale, X étant la plage et Y étant le changement d'altitude (appelé DAlt dans mon code). J'essaie de le convertir en une ligne de code afin que je puisse faire un programme pour calculer l'élévation basée sur des coordonnées données. Cependant, j'ai des problèmes avec ça. J'ai actuellement ceci:

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 

Ce qui n'est pas particulièrement agréable mais pour autant que je sache, cela devrait fonctionner. Cependant quand j'ai mis dans les valeurs que la vidéo j'ai eu l'équation d'utilisé, j'ai eu une réponse différente. Donc, il doit y avoir quelque chose qui ne va pas avec mon équation. J'ai essayé de le découper en différentes parties comme des variables séparées et de les calculer, puis en utilisant ces variables dans l'équation globale, et cela ne fonctionnait toujours pas et m'a donné une réponse qui était fausse d'une autre manière.

Je ne sais pas comment résoudre ce problème, et je me demande si la façon dont vb gère les longues équations est différente ou quelque chose comme ça.
Toute aide est très appréciée.

Répondre

2

Vous n'avez pas donné de données d'échantillon, donc je ne peux pas vérifier que cela donne la bonne réponse, mais il manque des parenthèses dans la dernière partie de votre équation.

Elevation = Math.Atan(((Velocity^2) + Math.Sqrt((Velocity^4) - (G * ((G * (Range^2)) + (2 * DAlt * (Velocity^2))))))/(G * Range)) 

Notez la parenthèse autour de la dernière G * Range.

La multiplication et la division ont la même priorité, elles sont donc évaluées de gauche à droite. Voir Operator Precedence in Visual Basic.

Vous divisaient tout par G, puis en multipliant le résultat par Range, alors que vous aviez besoin de multiplier par GRange, puis diviser tout par le résultat de cela.

Vous pouvez voir la différence dans cet exemple simple:

Console.WriteLine(3/4 * 5) ' Prints 3.75 
Console.WriteLine(3/(4 * 5)) ' Prints 0.15 
+0

Merci pour votre aide! J'ai supposé qu'il me manquait des parenthèses quelque part mais traverser tout cela était un cauchemar, j'ai essayé à plusieurs reprises de le résoudre et je ne pouvais pas. Cela produit la réponse en radians correcte?Pour convertir en degrés je dirais élévation = (tout cela) * (math.pi/180) à droite? – DatBrummie

+0

Mon diable, je l'ai eu à l'envers. Radians> degrés est 180/pi. Le programme semble fonctionner maintenant. En utilisant les mêmes valeurs que la vidéo, mon programme a donné 60,22 degrés, tandis que la vidéo a donné 61,06 degrés. Je ne vois pas pourquoi ce serait différent, mais c'est assez proche. Merci pour l'aide! – DatBrummie

+0

@thirdwaffle - Exemples de données fournies dans ma réponse. – dbasnett

1

Par curiosité, j'ai essayé le problème. Afin d'avoir des données de test, j'ai trouvé ce site Web, Range Tables For Mortars. J'ai testé avec le '82mm Mortar - Far' qui a une vitesse initiale de 200 m/s. Un problème que j'avais, et je ne sais pas si je l'ai corrigé correctement, était que la première partie de l'équation renvoyait des nombres négatifs ... J'ai également résolu pour le ±. Pour tester j'ai créé un formulaire avec un bouton pour effectuer le calcul, une zone de texte pour entrer la distance, et deux étiquettes pour montrer les angles. C'est ce que j'ai trouvé. En utilisant le site Web pour vérifier les calculs, le code semble correct.

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 

L'écriture de longues formules dans un groupe de parenthèses imbriquées ne sert à rien, à moins que vous ne soyez prêt à la confusion.

+0

Merci pour la réponse! Je ne m'attendais pas vraiment à ce que l'écriture de l'équation dans une longue ligne ait un quelconque avantage, c'est juste que c'était le meilleur moyen que j'avais à l'époque. Quand j'ai essayé de le diviser comme vous l'avez fait, j'ai eu des réponses qui étaient fausses d'une autre manière. Je peux essayer de le convertir comme vous l'avez fait, juste pour le rendre plus facile à lire. La vidéo dont j'ai eu l'équation était [celle-ci] (https://www.youtube.com/watch?v=A4SPene9Yxw) et il serait probablement facile de faire une simple feuille de calcul qui pourrait le calculer. Mais je cherchais juste une excuse pour pratiquer ma programmation. – DatBrummie

+1

@DatBrummie - désolé, ne voulait pas dire être dur. Convertissez-le et si vous avez des problèmes, demandez de l'aide à nouveau. – dbasnett