Gondus

Orbite V2

Jul 29th, 2025 (edited)
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.58 KB | Science | 0 0
  1. from matplotlib import pyplot as plt
  2. import numpy as np
  3. import math
  4. import scipy
  5. from scipy import special
  6. import scipy.constants
  7.  
  8. #interazione gravitazionale tra 2 corpi, usando la formula di Newton
  9. nome_corpo_maggiore = input("Inserisci il nome del corpo di massa maggiore: ")
  10. massa_maggiore = float(input(f"Inserisci la massa di {nome_corpo_maggiore} in kg: "))
  11. raggio_maggiore = float(input(f"Inserisci il raggio di {nome_corpo_maggiore} in m: "))
  12.  
  13. nome_corpo_minore = input("Inserisci il nome del corpo di massa minore: ")
  14. massa_minore = float(input(f"Inserisci la massa di {nome_corpo_minore} in kg: "))
  15. raggio_minore = float(input(f"Inserisci il raggio di {nome_corpo_minore} in m: "))
  16.  
  17. T = float(input(f"Inserisci il tempo di rivoluzione di {nome_corpo_minore} in s: "))
  18. e = float(input(f"Inserisci l'eccentricità dell'orbita di {nome_corpo_minore}: "))
  19.  
  20. while True:
  21.     condizione_stella = input(f"{nome_corpo_maggiore} è una stella? ")
  22.     if condizione_stella.lower() == "sì":
  23.         stella_switch = True
  24.         lum = float(input(f"Inserisci la luminosità di {nome_corpo_maggiore} rispetto al Sole: "))
  25.         lum_switch = True
  26.         condizione_albedo = input(f"L'albedo di {nome_corpo_minore} è noto? ")
  27.         if condizione_albedo.lower() == "sì":
  28.             albedo_switch = True
  29.             albedo = float(input(f"Inserisci l'albedo di {nome_corpo_minore}: "))
  30.             break
  31.         elif condizione_albedo.lower() == "no":
  32.             albedo_switch = False
  33.             break
  34.         else:
  35.             print("Input non valido")
  36.     elif condizione_stella.lower() == "no":
  37.         stella_switch = False
  38.         lum_switch = False
  39.         albedo_switch = False
  40.         break
  41.  
  42. while True:
  43.     condizione_satellite = input(f"{nome_corpo_minore} è un satellite artificale? ")
  44.     if condizione_satellite.lower() == "sì":
  45.         satellite_switch = True
  46.         break
  47.     elif condizione_satellite.lower() == "no":
  48.         satellite_switch = False
  49.         break
  50.  
  51. while True:
  52.     condizione_rotazione = input(f"Il periodo di rotazione di {nome_corpo_maggiore} è noto? ")
  53.     if condizione_rotazione.lower() == "sì":
  54.         rot = float(input(f"Inserisci il periodo di rotazione di {nome_corpo_maggiore} in s: "))
  55.         rotazione_switch = True
  56.         break
  57.     elif condizione_rotazione.lower() == "no":
  58.         rotazione_switch = False
  59.         break
  60.  
  61. #costanti
  62. G = scipy.constants.gravitational_constant
  63. AU = scipy.constants.astronomical_unit
  64. sigma = scipy.constants.Stefan_Boltzmann
  65. ly = scipy.constants.light_year
  66.  
  67. #calcoli
  68. a = np.cbrt(((T**2)*G*massa_maggiore)/(4*(np.pi**2))) #semiasse maggiore
  69. b = a*np.sqrt(1-e**2)
  70.  
  71. raggio_perielio = a*(1-e)
  72. raggio_afelio = a*(1+e)
  73. Lim_Roche = raggio_maggiore*2.44*((massa_maggiore/(4/3*np.pi*raggio_maggiore**3))/(massa_minore/(4/3*np.pi*raggio_minore**3)))**(1/3) #satelliti liquidi
  74.  
  75. velocità_perielio = np.sqrt(((G*massa_maggiore)/a)*((1+e)/(1-e)))
  76. velocità_afelio = np.sqrt(((G*massa_maggiore)/a)*((1-e)/(1+e)))
  77.  
  78. if stella_switch is True:
  79.     if lum_switch is True:
  80.         #da https://web.archive.org/web/20230314210750/https://www.planetarybiology.com/calculating_habitable_zone.html
  81.         raggio_abitabile_minimo = np.sqrt(lum/1.1)*AU #in AU il calcolo
  82.         raggio_abitabile_massimo = np.sqrt(lum/0.53)*AU #in AU il calcolo
  83.         if albedo_switch is True:
  84.             energia_stellare = lum*3.828e26
  85.             Temp_perielio = ((energia_stellare*(1-albedo))/(16*np.pi*sigma*(raggio_perielio)**2))**(1/4)
  86.             Temp_afelio = ((energia_stellare*(1-albedo))/(16*np.pi*sigma*(raggio_afelio)**2))**(1/4)
  87.  
  88. if rotazione_switch is True:
  89.     numero_orbite_giorno = rot/T
  90.  
  91.  
  92. #calcoli per il plot
  93. distanza_centro_fuoco = e*a
  94. angolo = np.linspace(0, 2*np.pi, 100000)
  95. x_orbita = a*np.cos(angolo) #costruzione orbita sull'asse x
  96. y_orbita = b*np.sin(angolo) #costruzione orbita sull'asse y
  97. distanza_corpomaggiore_centro = -distanza_centro_fuoco #per semplicità nella visualizzazione, si assume quindi che il perielio sia a sx nel plot e l'afelio a dx nel plot
  98.  
  99. if stella_switch is True:
  100.     abitabile_minimo_x = raggio_abitabile_minimo*np.cos(angolo) #raggio abitabile min
  101.     abitabile_minimo_y = raggio_abitabile_minimo*np.sin(angolo)
  102.     abitabile_massimo_x = raggio_abitabile_massimo*np.cos(angolo) #raggio abitabile max
  103.     abitabile_massimo_y = raggio_abitabile_massimo*np.sin(angolo)
  104.     #concatenazione per fare percorso chiuso
  105.     #si crea un anello, prima con dati in senso antiorario (min_x,y) e poi in senso orario (inverso di max_x,y)
  106.     x_R = np.concatenate([abitabile_minimo_x, abitabile_massimo_x[::-1]])
  107.     y_R = np.concatenate([abitabile_minimo_y, abitabile_massimo_y[::-1]])
  108.  
  109. if satellite_switch is True:
  110.     raggio_x_corpomaggiore = raggio_maggiore*np.cos(angolo)
  111.     raggio_y_corpomaggiore = raggio_maggiore*np.sin(angolo)
  112.  
  113. #costruzione orbita
  114. if rotazione_switch is False:
  115.     plt.plot(x_orbita,
  116.             y_orbita,
  117.             label=f"Orbita di {nome_corpo_minore} attorno a {nome_corpo_maggiore}\nTempo di rivoluzione: {(((T/60)/60)/24):.3f} d = {((((T/60)/60)/24)/365):.3f} y\nEccentricità: {e}")
  118. elif rotazione_switch is True:
  119.     plt.plot(x_orbita,
  120.             y_orbita,
  121.             label=f"Orbita di {nome_corpo_minore} attorno a {nome_corpo_maggiore}\nTempo di rivoluzione: {(((T/60)/60)/24):.3f} d = {((((T/60)/60)/24)/365):.3f} y\nNumero di orbite attorno a {nome_corpo_maggiore} in un giorno: {(numero_orbite_giorno):.3f}\n(Periodo di rotazione di {nome_corpo_maggiore}: {(((rot/60)/60)/24):.3f} d = {((((rot/60)/60)/24)/365):.3f} y)\nEccentricità: {e}")
  122. plt.scatter(distanza_corpomaggiore_centro,
  123.             0,
  124.             label=f"Posizione di {nome_corpo_maggiore}",
  125.             zorder = 5,
  126.             color="yellow")
  127.  
  128. if albedo_switch is False and satellite_switch is False:
  129.     plt.scatter(raggio_afelio+distanza_corpomaggiore_centro,
  130.                 0,
  131.                 label=f"Afelio dell'orbita di {nome_corpo_minore}\nAfelio: {((raggio_afelio)/1000):.3f} km = {((raggio_afelio)/AU):.3f} AU = {((raggio_afelio)/ly):.3f} ly\nVelocità: {((velocità_afelio)*3.6):.3f} km/h",
  132.                 zorder = 5,
  133.                 color="green")
  134.     plt.scatter(-(raggio_perielio-distanza_corpomaggiore_centro),
  135.                 0,
  136.                 label=f"Perielio dell'orbita di {nome_corpo_minore}\nPerielio: {((raggio_perielio)/1000):.3f} km = {((raggio_perielio)/AU):.3f} AU = {((raggio_perielio)/ly):.3f} ly\nVelocità: {((velocità_perielio)*3.6):.3f} km/h",
  137.                 zorder = 5,
  138.                 color="red")
  139.  
  140. elif albedo_switch is True and satellite_switch is False:
  141.     plt.scatter(raggio_afelio+distanza_corpomaggiore_centro,
  142.                 0,
  143.                 label=f"Afelio dell'orbita di {nome_corpo_minore}\nAfelio: {((raggio_afelio)/1000):.3f} km = {((raggio_afelio)/AU):.3f} AU = {((raggio_afelio)/ly):.3f} ly\nVelocità: {((velocità_afelio)*3.6):.3f} km/h\nTemperatura: {((Temp_afelio)-273.15):.3f}°C",
  144.                 zorder = 5,
  145.                 color="green")
  146.     plt.scatter(-(raggio_perielio-distanza_corpomaggiore_centro),
  147.                 0,
  148.                 label=f"Perielio dell'orbita di {nome_corpo_minore}\nPerielio: {((raggio_perielio)/1000):.3f} km = {((raggio_perielio)/AU):.3f} AU = {((raggio_perielio)/ly):.3f} ly\nVelocità: {((velocità_perielio)*3.6):.3f} km/h\nTemperatura: {((Temp_perielio)-273.15):.3f}°C",
  149.                 zorder = 5,
  150.                 color="red")
  151.  
  152. if stella_switch is True:
  153.     plt.plot(abitabile_minimo_x+distanza_corpomaggiore_centro,
  154.             abitabile_minimo_y,
  155.             label = f"Limite minore dell'area abitabile di {nome_corpo_maggiore}\nRaggio = {(raggio_abitabile_minimo/AU):.3f} AU",
  156.             zorder = 5,
  157.             color = "black"
  158.             )
  159.     plt.plot(abitabile_massimo_x+distanza_corpomaggiore_centro,
  160.             abitabile_massimo_y,
  161.             label = f"Limite maggiore dell'area abitabile di {nome_corpo_maggiore}\nRaggio = {(raggio_abitabile_massimo/AU):.3f} AU",
  162.             zorder = 5,
  163.             color = "black"
  164.             )
  165.     plt.fill(x_R+distanza_corpomaggiore_centro,
  166.             y_R,
  167.             label = f"Area abitabile di {nome_corpo_maggiore}",
  168.             color="lightgreen",
  169.             alpha=0.4)
  170.  
  171. if satellite_switch is True:
  172.     plt.scatter(raggio_afelio+distanza_corpomaggiore_centro,
  173.                 0,
  174.                 label=f"Apogeo dell'orbita di {nome_corpo_minore}\nApogeo: {((raggio_afelio-raggio_maggiore)/1000):.3f} km = {((raggio_afelio)/AU):.3f} AU\nVelocità: {((velocità_afelio)*3.6):.3f} km/h",
  175.                 zorder = 5,
  176.                 color="green")
  177.     plt.scatter(-(raggio_perielio-distanza_corpomaggiore_centro),
  178.                 0,
  179.                 label=f"Perigeo dell'orbita di {nome_corpo_minore}\nPerigeo: {((raggio_perielio-raggio_maggiore)/1000):.3f} km = {((raggio_perielio)/AU):.3f} AU\nVelocità: {((velocità_perielio)*3.6):.3f} km/h",
  180.                 zorder = 5,
  181.                 color="red")
  182.     plt.plot(raggio_x_corpomaggiore+distanza_corpomaggiore_centro,
  183.             raggio_y_corpomaggiore,
  184.             color="black",
  185.             zorder=5)
  186.     plt.fill(raggio_x_corpomaggiore+distanza_corpomaggiore_centro,
  187.             raggio_y_corpomaggiore,
  188.             color="red",
  189.             label=f"Area occupata da {nome_corpo_maggiore}\nRaggio: {(raggio_maggiore):.3f} m",
  190.             alpha=0.4)
  191.  
  192. plt.grid()
  193. plt.axis("equal") #evita distorsione cerchi
  194. plt.legend(loc="upper right", fontsize=7.5)
  195. plt.xlabel("Raggio (m)")
  196. plt.ylabel("Raggio (m)")
  197. plt.title(f"Orbita di {nome_corpo_minore} attorno a {nome_corpo_maggiore}")
  198. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment