Condition sur les valeurs d'un tableau en Python

Résolu

Bonjour,

J'ai fait un programme simulant un orbite autour d'un astre en fonction des conditions initiales. Mais pour l'instant, le programme affiche tout l'orbite, y compris la partie de l'orbite théorique sous la surface. Je voulais savoir comment faire pour afficher uniquement la partie émerger de l'orbite (l'orbite réel quoi) ? C'est a dire tel que r >= R, ou R est le rayon de l'astre. Sachant que r est un tableau mais pas un tableau numpy classique, c'est une valeure inclus dans un tableau odeint avec des histoire d'intégration. Donc j'ai essayer de faire any(r) >= R ou all(r) >= R, mais ca marche pas.

Merci


Windows / Chrome 106.0.0.0

4 réponses

  1. from scipy.integrate import odeint
    import numpy as np
    from matplotlib import pyplot as plt
    from math import pi
    from math import sqrt
    t = np.linspace(0, 50000, 10000)  
    
    G = 6.67e-11
    M = 8.6e19
    R = 252.2
    A = 0
    
    def F(f, t):
        [r, rp, theta] = f
        thetap = C /(r**2)
        return [rp,r*thetap**2-G*M/(r**2),thetap]
    
    n = input("\n" + "Vitesse orthoradiale initiale en m/s: ") 
    p = input("\n" + "Vitesse radiale initiale en m/s: ") 
    m = input("\n" + "Altitude initiale par rapport à la surface en km: ")
    
    r0 = float(m)*1000 + float(R)*1000
    thetap0 = float(n) / r0
    C = thetap0 * (r0 ** 2)
    f0 = [r0, p, 0]
    f = odeint(F, f0, t)
    r = f[:, 0]
    theta = f[:, 2]
    # =============================================================================
    # 
    # ============================================================================= 
    x = (r * np.cos(theta))/1000
    y = (r * np.sin(theta))/1000
    
    
    circle1 = plt.Circle((0, 0), R+A , color='b')
    circle2 = plt.Circle((0, 0), R , color='sienna')
    fig, ax = plt.subplots()
    ax.set_aspect(1)
    ax.add_artist(circle1)
    ax.add_artist(circle2)
    
    plt.plot(x, y, "steelblue")
    plt.axis("equal") 
    plt.show()
        
        
    a = round(((max(r)/1000)-R), 2)
               
    p = round(((min(r)/1000)-R), 2)
    
    d = ((a+p+2*R)/2)*1000
    
    P = sqrt((4*(pi**2)*(d**3))/(G*M))
    
    k = round((P/60), 2)
               
    print("\n" + "Périgée = " + str(p) + " km" + "\n", "Apogée = " + str(a) + " km")
    
    print("\n" + "Période de révolution = " + str(k) + " min" )
    
    if a < A:
        print("\n" + """Votre orbite pénètre l'atmosphère !""")
    if p < A:
        print("\n" + """Votre orbite pénètre l'atmosphère !""")
    
    if p < 0:
        print("\n" + "Votre orbite pércute le sol !")

    Donc la les paramètres de M, R et A sont ceux de Encelade mais peut importe. C'est surtout au niveau de plt.plot et par la qu'il faut que j'ajoute une condition pour afficher uniquement l'orbite au dessus de la surface.

    0
    1. Contributeur Ambassadeur

      peut-être ainsi:

      Rm=R*1000
      r[r<Rm]=None
      0
    2. Contributeur Ambassadeur
      @yg_be

      ou bien:

      r = f[:, 0]
      Rm=R*1000
      fl=r>Rm
      r=r[fl]
      theta = f[:, 2]
      theta=theta[fl]
      0
  2. Si j'ai bien compris, tu veux afficher seulement ce qui est au dessus de l'écliptique?
    J'imagine que tu devras calculer les projections sur l'écliptique et ne garder que les position avec l'autre coordonnée positive?

    0
    1. Contributeur Ambassadeur

      Il souhaite ne pas afficher la partie de la trajectoire qui est sous la surface de l'astre. 

      Comme il utilise des coordonnées polaires, centrée sur le centre de l'astre, il est très simple d'identifier les points à éliminer.

      J'ai fait deux suggestions, une qui remplace par "none" la coordonnée "distance" des points à éliminer, l'autre qui élimine les points non désirés.

      0
  3. Merci mais l'astuce de ygbe fonctionne.

    0