Движение снаряда: результаты показывают большую разницу между линией с сопротивлением воздуха и линией без него.

Я симулирую движение снаряда с помощью python на Spyder, один с сопротивлением воздуха, а другой без него. Я начал с того, что подписался на страницу this="nofrerol " упражнение. Это побудило меня сделать движение снаряда с сопротивлением воздуха. Для сравнения я попытался самостоятельно изобразить движение снаряда без сопротивления воздуха на том же графике с теми же параметрами. Однако полученный график стал для меня неожиданностью, так как он выглядит немного не так. Между этими двумя линиями большая разница с точки зрения диапазона, поскольку другие похожие графики, с которыми я встречался в Интернете, показывают только небольшую разницу.

Мой график:

введите описание изображения здесь

(меньший - тот с сопротивлением, а больший - без него)

Мои вопросы:

  1. Что вызвало это? Это потому, что сила сопротивления, которую я указал, включает только коэффициент сопротивления и скорость, что сделало график меньше, чем тот, который также включает площадь поперечного сечения и rho?

  2. Я делаю это очень сложно, и как бы вы изменили его, чтобы сделать его более эффективным и аккуратным?

Было бы здорово, если бы вы также указали на любые мои ошибки.

import numpy as np
import matplotlib.pyplot as plt

# Model parameters
M = 1.0          # Mass of projectile in kg
g = 9.8          # Acceleration due to gravity (m/s^2)
V = 80           # Initial velocity in m/s
ang = 60.0       # Angle of initial velocity in degree
Cd = 0.005       # Drag coefficient
dt = 0.5         # time step in s

# Set up the lists to store variables
# Start by putting the initial velocities at t=0
t = [0]                         # list to keep track of time
vx = [V*np.cos(ang/180*np.pi)]  # list for velocity x and y components
vy = [V*np.sin(ang/180*np.pi)]

# parameters for the projectile motion without drag force
t1=0
vx_nodrag=V*np.cos(ang/180*np.pi)
vy_nodrag=V*np.sin(ang/180*np.pi)

while (t1 < 100):
    x_nodrag=vx_nodrag*t1
    y_nodrag=vy_nodrag*t1+(0.5*-9.8*t1**2)
    plt.ylim([0,500])
    plt.xlim([0,570])
    plt.scatter(x_nodrag, y_nodrag)
    print(x_nodrag,y_nodrag)
    t1=t1+dt

# Drag force
drag = Cd*V**2                      # drag force 

# Create the lists for acceleration components
ax = [-(drag*np.cos(ang/180*np.pi))/M]        
ay = [-g-(drag*np.sin(ang/180*np.pi)/M)]

# Use Euler method to update variables
counter = 0
while (counter < 100):
    t.append(t[counter]+dt)            # increment by dt and add to the list of time 
    vx.append(vx[counter]+dt*ax[counter])  
    vy.append(vy[counter]+dt*ay[counter])  

    # With the new velocity calculate the drag force
    vel = np.sqrt(vx[counter+1]**2 + vy[counter+1]**2)   
    drag = Cd*vel**2                                  
    ax.append(-(drag*np.cos(ang/180*np.pi))/M)    
    ay.append(-g-(drag*np.sin(ang/180*np.pi)/M))    
    
    # Increment the counter by 1
    counter = counter +1

x=[0]#creating a list for x
y=[0]#creating a list for y

counter1=0
while (counter1<50):

    #t.append(t[counter1]+dt),t already has a list.
    x.append(x[counter1]+dt*vx[counter1])    
    y.append(y[counter1]+dt*vy[counter1])  
    plt.ylim([0,500])
    plt.xlim([0,570])
    plt.plot(x,y)
    #print(x,y)
    counter1=1+counter1

# Let's plot the trajectory
plt.plot(x,y,'ro')
plt.ylabel("height")
plt.xlabel("range")
print("Range of projectile is {:3.1f} m".format(x[counter]))

person gggjackie    schedule 24.12.2020    source источник
comment
Сюжеты должны быть разными, когда у вас есть сопротивление воздуха, вы теряете энергию, и вы должны достичь более короткого промежутка. Если вы уменьшите коэффициент лобового сопротивления, вы увидите, что каждый раз вы увеличиваете диапазон. При этом у вас есть ошибка в вашем коде, потому что вы получаете больший диапазон с небольшими коэффициентами сопротивления, чем при полном отсутствии перетаскивания.   -  person nicoguaro    schedule 24.12.2020
comment
Привет спасибо за ответ. Как вы посоветуете мне исправить ошибку?   -  person gggjackie    schedule 24.12.2020
comment
Я не знаю, в чем ошибка. Но, возможно, вы могли бы попробовать использовать массивы numpy вместо списков. Кроме того, вы можете обернуть все в один цикл. Кроме того, возможно, уменьшив размер шага, вы получите лучшие результаты.   -  person nicoguaro    schedule 24.12.2020


Ответы (1)


  1. Да, вам обязательно нужно включить все параметры снаряда, так как общее пройденное расстояние очень чувствительно к этому.
  2. Обычно старайтесь работать с функциями, которые затем можно вызывать для циклов. Это упрощает чтение кода и делает его более пригодным для повторного использования. Реализуйте, например, функцию, которая вычисляет новый временной шаг. Также работайте с массивами numpy как векторами вместо того, чтобы иметь vx и vy отдельно.

Кроме того, в ваших расчетах есть ошибка. При вычислении новых скоростей вам также необходимо вычислить обновленный угол. Это потому, что на каждом шаге у вас есть новый угол (т.е. в конце полета сила сопротивления в направлении y имеет знак, противоположный гравитации).

Например:

    vel = np.sqrt(vx[counter+1]**2 + vy[counter+1]**2)   
    drag = Cd*vel**2


    # calculate new angle for force separation
    a, v = np.array([1,0]), np.array([vx[counter+1], vy[counter+1]])
    if vy[counter+1] > 0:
        ang = np.arccos( np.dot(a,v) / (1*np.linalg.norm(v)) )
    else:
        ang = 2*np.pi - np.arccos( np.dot(a,v) / (1*np.linalg.norm(v)) )   

                           
    ax.append(-(drag*np.cos(ang))/M)    
    ay.append(-g-(drag*np.sin(ang)/M))
person bluesky    schedule 22.02.2021