lundi 10 août 2020

Astronomie : libnova

Il y a quelques années j'avais écrit quelques programmes de calcul de l'heure de lever et de coucher du soleil. J'ai découvert ces jours-ci une librairie de calculs d'astronomie qui fait tout ce qu'on peut imaginer.

Introduction

La librairie libnova est destinée aux programmeurs C/C++ qui veulent faire des calculs de mécanique céleste ou d'astronomie. Elle fait partie du projet Nova qui se veut un environnement pour les astronomes amateurs. Il s'apparente, semble-t-il, à Stellar, mais est dédié à Gnome et Gtk.

libnova est développée sous la licence GNU LGPL. Elle s'appuie sur le livre de Jean Meeus Calculs astronomiques à l'usage des amateurs.

Le site de libnova est à l'adresse http://libnova.sourceforge.net/

Installation

La librairie s'installe simplement en utilisant votre gestionnaire de paquets. Par exemple pour Archlinux (qui est la meilleure distribution linux :D) on fait simplement :

sudo pacman -S libnova

et pour Debian et fils on devrait faire :

sudo apt istall libnova

La documentation peut-etre installée à partir du fichier compressé se trouvant ici

Exemple d'utilisation de libnova

Voici en téléchargement une de mes dernieres version d'un programme de calcul de lever et coucher de soleil sun.c. Et voici presque le même utilisant libnova.

/*
:w | !gcc -lnova % -o %<
:w | !gcc -lnova % -o %< && ./%<
*/
#include <stdio.h>
#include <libnova/solar.h>
#include <libnova/julian_day.h>
#include <libnova/rise_set.h>
#include <math.h>
// print hours:minutes
static void print_time(char* c, struct ln_zonedate *date)
{
   printf("%s  %02d:%02d  ", c, date->hours, date->minutes);
}
void print_time_diff(struct ln_rst_time rst)
{
   double d = (rst.set - rst.rise)*24;
   int h = (int)d;
   int m = round((d - h)*60);
   printf("Δ = %d:%02d", h, m);
}
 
int main (int argc, const char *argv[])
{
   struct ln_rst_time rst;
   struct ln_zonedate rise, set;
   struct ln_lnlat_posn observer;
   double JD;
   struct ln_date date;
 
   /* get Julian day from local time */
   JD = ln_get_julian_from_sys();
   ln_get_date(JD, &date);
   /* observers location (Exoudun), used to calc rst */
   observer.lat = 46.344467; /* 55.92 N */
   observer.lng = -0.089848; /* 3.18 W */
 
   /* rise, set and transit */
   if (ln_get_solar_rst(JD, &observer, &rst) != 0)
      fprintf(stdout, "Sun is circumpolar\n");
   else {
      ln_get_local_date(rst.rise, &rise);
      ln_get_local_date(rst.set, &set);
      printf("%02d/%02d/%d   ", date.days, date.months, date.years);
      print_time("", &rise);
      print_time("", &set);
      print_time_diff(rst);
      puts("");
   }
 
   return 0;
}

Il s'inspire largement du programme de même nom donné en exemple par la documentation.

Avant toute considération, je dois avouer que je bute sur une difficulté que j'ai contournée en ajoutant les lignes 29 et 33. Cet écueil consistait à afficher un jour erroné (le suivant) dans la date.

Commentaires

Le programme se compile avec la commande : gcc -lnova -o sun sun.c.

Lignes 5 à 9

Inclusion des fichiers entêtes de la librairie.

Lignes 11 à 14

Fonction utilisé lignes 38 et 39 pour afficher l'heure sous la forme hh:mm.

lignes 25 à 29

Variables utilisées par le programme.

Ligne 29

J'ai dû ajouter cette variable que j'initialise à la ligne 33 pour obtenir une valeur correcte du jour dans l'affichage de la ligne 44. En utilisant l'une des variables rise ou set j'obtenais le bon mois, la bonne année mais le jour suivant.

Lignes 35 et 36

Position de l'observateur : latitude, longitude.

Ligne 39

Calcul des heures de lever et coucher de soleil. JD est le jour julien, observer est la position de l'observateur, rstest la structure qui contiendra le résultat.

Lignes 42 et 43

Conversions en heure locale.

Remarque : la fonction ln_get_local_date n'est pas commentée dans la documentation.

Lignes 45 à 46

Affichage de la date et des heures de lever et coucher du soleil.




Réalisé avec Qlam - LGPL