Advertisement
EditorRUS

ballistic.py

Jul 4th, 2015
344
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.93 KB | None | 0 0
  1. from math import *
  2.  
  3. g = 9.81
  4.  
  5. mass = 1
  6. density = 1.225
  7. drag_coeff = 0.1
  8. area = 1
  9. zero_velocity = 100
  10. zero_angle = radians(45)
  11. ls = 30
  12. modes = 1
  13.  
  14. def menu():
  15.     while 1:
  16.         print(\
  17.     """Make your choice:
  18.    1. Start simulation
  19.    0. Exit"""
  20.               )
  21.         choice = -1
  22.         while not (int(choice) in range(4)):
  23.             choice = input("-->")
  24.         choice = int(choice)
  25.         elif (choice == 1):
  26.             options()
  27.         elif (choice == 0):
  28.             return
  29. def is_int(value):
  30.     try:
  31.         value = int(value)
  32.     except:
  33.         return 0
  34.     return 1
  35.  
  36. def is_float(value):
  37.     try:
  38.         value = float(value)
  39.     except:
  40.         return
  41.     return 1
  42.  
  43. def print_options_menu():
  44.     strings = ['1','2']
  45.     str_modes = ["Without air drag", "Laminar air drag"]
  46.     for x in range(2):
  47.         if (modes&2**x):
  48.             strings[x] = "*"+str_modes[x]+"*"
  49.         else:
  50.             strings[x] = str_modes[x]
  51.     print(\
  52. """
  53. Body:
  54.        1: m = {mass:.3f} kg -- mass
  55.        2: v = {zero_velocity:.3f} m/s -- zero velocity
  56.        3: a = {zero_angle:.3f} degrees -- zero angle
  57.        4: S = {area:.3f} m^2 -- cross-sectional area
  58.        5: C = {drag_coeff:.3f} -- drag coeff
  59. Environment:
  60.        6: g = {g:.3f}m/s^2 -- acceleration of gravity
  61.        7: p = {density:.3f} kg/m^3 -- density of medium
  62. Simulation:
  63.        8: Field size = {ls} symbols
  64. Operations:
  65.        9:  {str0}
  66.        10: {str1}
  67.        11: Start simulation
  68.        0: Exit
  69.        """.format(\
  70.             mass=mass,\
  71.             zero_velocity=zero_velocity,\
  72.             zero_angle=degrees(zero_angle),\
  73.             area=area,\
  74.             drag_coeff=drag_coeff,\
  75.             g=g,\
  76.             density=density,\
  77.             ls=ls,\
  78.             str0 = strings[0],\
  79.             str1 = strings[1]))
  80.  
  81. def options():
  82.     global modes
  83.     while(1):
  84.         the_num = -1
  85.         drag = 0
  86.         print_options_menu()
  87.         print("Choose the variable number you wish to change")
  88.         while(1):
  89.             the_num = input("-->")
  90.             if (not is_int(the_num)):
  91.                 print("Not an integer is entered, try again")
  92.                 continue
  93.             the_num = int(the_num)
  94.             if (the_num < 0 or the_num > 12):
  95.                 print("Incorrect value entered, try again")
  96.                 continue
  97.             break
  98.         if (the_num == 0): break
  99.         if (the_num == 11):
  100.             bal_sim(modes)
  101.             continue
  102.         elif (the_num >= 9):
  103.             modes = modes^2**(the_num-9)
  104.             continue
  105.         print("Now enter a value you wish for chosen variable to be")
  106.        
  107.         rules_negative = [0, 0, 1, 0, 0, 0, 0, 0]
  108.         rules_upto1 = [0, 0, 0, 0, 0, 0, 0, 0]
  109.         rules_upto90 = [0, 0, 1, 0, 0, 0, 0, 0]
  110.         rules_int = [0, 0, 0, 0, 0, 0, 0, 1]
  111.         rules_positive = [1, 1, 0, 1, 1, 1, 1, 1]
  112.         rules = ["mass", "zero_velocity", "zero_angle", "area", "drag_coeff", "g", "density", "ls"]
  113.        
  114.         print("Your value must be...")
  115.         if(rules_negative[the_num-1]):
  116.             print(" not negative")
  117.         if(rules_upto1[the_num-1]):
  118.             print(" be less or equal to 1 modulo")
  119.         if(rules_upto90[the_num-1]):
  120.             print(" be less or equal to 90 modulo")
  121.         if(rules_positive[the_num-1]):
  122.             print(" positive")
  123.         the_value = 0
  124.         while(1):
  125.             the_value = input("-->")
  126.             if (not is_float(the_value)):
  127.                 print("Not a number is entered, try again")
  128.                 continue
  129.             the_value = float(the_value)
  130.             is_incorrect = 0
  131.             if (rules_negative[the_num-1] and the_value < 0):  is_incorrect=1
  132.             if ((rules_upto1[the_num-1] and the_value > 1) or (rules_negative[the_num-1] and the_value < -1)): is_incorrect=1
  133.             if ((rules_upto90[the_num-1] and the_value > 90) or (rules_negative[the_num-1] and the_value < -90)):   is_incorrect=1
  134.             if (rules_int[the_num-1] and not(int(the_value) == the_value)):   is_incorrect=1
  135.             if (rules_positive[the_num-1] and the_value <= 0):   is_incorrect=1
  136.             if (is_incorrect):
  137.                 print("Incorrect value entered, try again")
  138.                 continue
  139.             if (rules_upto90[the_num-1]):
  140.                 the_value = radians(the_value)
  141.             if (rules_int[the_num-1]):
  142.                 the_value = int(the_value)
  143.             break
  144.         globals()[rules[the_num-1]] = the_value
  145.  
  146. def approximate_input(to_reach, error, constants, variable, formula, goes_down, default_value=0, RPV=0, var_max=0, fun_RPV=0, fun_min=0):
  147.     var = default_value
  148.     dvar = 1
  149.     dm = 0
  150.     current_vars = constants
  151.     current_vars[variable] = var
  152.     fx = eval(formula, globals(), current_vars)
  153.     while 1:
  154.         delta_var = var
  155.         if (abs(fx-to_reach) <= error):
  156.             return var
  157.         if (fx < to_reach and not goes_down):
  158.             if (dm==2):
  159.                 dvar = dvar / 2
  160.             dm = 1
  161.             if (RPV and var+dvar > var_max):
  162.                 var = var - dvar
  163.             else:
  164.                 var = var + dvar
  165.             current_vars[variable] = var
  166.         elif (fx > to_reach and goes_down):
  167.             if (dm==2):
  168.                 dvar = dvar / 2
  169.             dm = 1
  170.             if (RPV and var+dvar > var_max):
  171.                 var = var - dvar
  172.             else:
  173.                 var = var + dvar
  174.             current_vars[variable] = var
  175.         elif (fx > to_reach and not goes_down):
  176.             if (dm==1):
  177.                 dvar = dvar / 2
  178.             dm = 2
  179.             if (RPV and var+dvar > var_max):
  180.                 var = var + dvar
  181.             else:
  182.                 var = var - dvar
  183.             current_vars[variable] = var
  184.         elif (fx < to_reach and goes_down):
  185.             if (dm==1):
  186.                 dvar = dvar / 2
  187.             dm = 2
  188.             if (RPV and var+dvar > var_max):
  189.                 var = var + dvar
  190.             else:
  191.                 var = var - dvar
  192.             current_vars[variable] = var
  193.         fx = eval(formula, globals(), current_vars)
  194.         delta_var = delta_var - var
  195.         delta_var = var - delta_var
  196.         if (fun_RPV):
  197.             if (fx < fun_min):
  198.                 var = var + delta_var
  199.        
  200.  
  201. def lar1hfyt(t, k, vy): #Laminar Air drag First Half Y(t)
  202.     kt = k*t
  203.     return k**-2 * (g * (-kt - e**-kt + 1) + vy * (k - k*e**-kt))
  204.  
  205. def lar2hfyt(t, k, my):
  206.     return (my*k**2 + g*k*t - g*e**(k*t)+g)/k**2
  207.  
  208. def larfxt (t, k, vx): #Laminar Air drag x(t)
  209.     return (vx-vx*e**(-k*t))/k
  210.  
  211. def larftx (x, k, vx): #Laminar Air drag t(x)
  212.     return (log(vx / (vx-x*k)) / k)
  213.  
  214. def tarfvt (t, k, vy):
  215.     anti_gk = sqrt(k/g)
  216.     gk = sqrt(g*k)
  217.     antik2gk = sqrt(g/k)
  218.    
  219.     return -antik2gk * tan(t*gk - atan(vy*anti_gk))
  220.    
  221. def bal_sim(mode=1):
  222.     vx = zero_velocity * cos(zero_angle)
  223.     vy = zero_velocity * sin(zero_angle)
  224.     the_trajectory_map = [[' ' for y in range(ls+1)] for x in range(ls+1)]
  225.     info = dict()
  226.     sd = 0
  227.     if (mode&2**0):
  228.         if (not g):
  229.             # Special case of no gravity
  230.             print("Not implemented for zero-gravity yet")
  231.             return
  232.         fly_time = 2*vy / g #Fly time
  233.         mx = vx*fly_time
  234.         my = (vy**2) / (2*g)
  235.         true_my = (zero_velocity**2) / (2*g)
  236.         sx = mx / ls
  237.         sy = true_my / ls
  238.         sd = max(sx, sy)
  239.         for yy in range(ls+1):
  240.             current_y_rounded = yy*sd
  241.            
  242.             D = vy**2 - 2*g*current_y_rounded
  243.             if (D < 0): continue
  244.             D = D**0.5
  245.             t1= (vy - D) / g
  246.             t2= (vy + D) / g
  247.            
  248.             corresponding_fx1 = (vx*t1)
  249.             corresponding_fx1 = round(corresponding_fx1 / sd)
  250.             corresponding_fx2 = (vx*t2)
  251.             corresponding_fx2 = round(corresponding_fx2 / sd)
  252.             if (0 <= corresponding_fx1 < ls+1):
  253.                 the_trajectory_map[yy][corresponding_fx1] = 'X'
  254.             if (0 <= corresponding_fx2 < ls+1):
  255.                 the_trajectory_map[yy][corresponding_fx2] = 'X'
  256.         for xx in range(ls+1):
  257.             current_x_rounded = xx*sd
  258.             t1 = current_x_rounded / vx
  259.             corresponding_fy1 = (vy*t1 - (0.5*g*t1**2))
  260.             corresponding_fy1 = round(corresponding_fy1 / sd)
  261.             if (0 <= corresponding_fy1 < ls+1):
  262.                 the_trajectory_map[corresponding_fy1][xx] = 'X'
  263.         info['arlmx'] = mx
  264.         info['arlmy'] = my
  265.         info['arltif'] = fly_time
  266.     if (mode&2**1): #Laminar drag
  267.         k = 0.5*area*drag_coeff*density/mass
  268.         #y(t) = (g (-k t-e^(-k t)+1)+v_0 (k-k e^(-k t)))/k^2 -- first half, C is Vy0
  269.         #y(t) = (C k^2+g k t-g e^(k t)+g)/k^2 -- second half, C is My
  270.         #x(t) = (C-C e^(-k t))/k, C is Vx0
  271.         myt = log(1 + k*vy / g) / k #Maximum Y Time
  272.         my  = lar1hfyt(myt, k, vy) #Maximum Y
  273.         warmy = 0.5 * vy**2 / g #Without Air Drag Maximum Y
  274.         sy = warmy / ls
  275.         sht = approximate_input(sy / 2, sy / 2, locals(), "t", "lar2hfyt(t, k, my)", 1)
  276.         tif = sht + myt #Time in flight
  277.         mx = (vx-vx*e**(-k*tif))/k
  278.         warmx = vx*tif
  279.         sx = warmx / ls
  280.         if (not sd):
  281.             sd = max(sx, sy)
  282.  
  283.         for xx in range(ls+1):
  284.             cx = xx * sd
  285.             if (cx > mx): continue
  286.             t = larftx(cx, k, vx)
  287.             y0 = 0
  288.             if (t<=myt):
  289.                 y0 = lar1hfyt(t, k, vy)
  290.             else:
  291.                 y0 = lar2hfyt(t-myt, k, my)
  292.             y0 = round(y0 / sd)
  293.             the_trajectory_map[y0][xx] = 'X'
  294.         for yy in range(ls+1):
  295.             cy = yy * sd
  296.             if (cy > my):  continue
  297.             t0 = approximate_input(cy, sd / 2, locals(), "t", "lar1hfyt(t, k, vy)", 0, 0, 1, myt)
  298.             t1 = approximate_input(cy, sd / 2, locals(), "t", "lar2hfyt(t, k, my)", 1, 0, 1, tif)
  299.             x0 = larfxt(t0, k, vx)
  300.             x1 = larfxt(myt+t1, k, vx)
  301.             x0 = round(x0 / sd)
  302.             x1 = round(x1 / sd)
  303.             the_trajectory_map[yy][x0] = 'X'
  304.             the_trajectory_map[yy][x1] = 'X'
  305.         true_mx = warmx
  306.         true_my = warmy
  307.         fly_time = tif
  308.         info['larmx'] = mx
  309.         info['larmy'] = my
  310.         info['lartif'] = tif
  311.  
  312.     for yy in range(ls, -1, -1):
  313.         for xx in range(ls+1):
  314.             print(the_trajectory_map[yy][xx], end='')
  315.         print(": {0:<} m".format(int(yy*sd)))
  316.     if (mode&2**0):
  317.         print("Dragless mode info:")
  318.         print(" Maximum length: ", info['arlmx'], ' meters')
  319.         print(" Maximum height: ", info['arlmy'], ' meters')
  320.         print(" In flight for: ", info['arltif'], ' seconds')
  321.     if (mode&2**1):
  322.         print("Laminar drag mode info:")
  323.         print(" Maximum length: ", info['larmx'], ' meters')
  324.         print(" Maximum height: ", info['larmy'], ' meters')
  325.         print(" In flight for: ", info['lartif'], ' seconds')
  326.        
  327. menu()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement