Saturday, June 17, 2017

Un po' di tools di base

La libreria standard di Python è fornitissima di funzioni pronte all'uso, ma per il nostro modesto lavoro di programmatori di software astrologico è bene che ci dotiamo di strumenti fatti apposta per lo scopo.

Per prima cosa apriremo un file tools.py con un editor a nostra scelta, in cui raccoglieremo tutte le funzioni che andremo via via creando in modo da poterle richiamare facilmente.

Per prime definiremo delle funzioni goniometriche di supporto alle operazioni sulle coordinate.

La libreria standard ha già queste funzioni, pero' si applicano ai gradi misurati in radianti (in cui l'angolo piatto vale 2 pigreco, per intenderci), mentre molte delle formule disponibili usano la misura in gradi.

Per prime le funzioni seno, coseno, tangente e arctangente2 (è la funzione inversa della tangente, ma a differenza della funzione arctangente normale effettua alcuni controlli sul segno degli operandi, risolvendo il dubbio sul corretto posizionamento dell'angolo nei quadranti, come si vede nellla tabella seguente):

Python 2.7.13 (default, Jan 19 2017, 14:48:08) 
[GCC 6.3.0 20170118] on linux2
Type "copyright", "credits" or "license()" for more information.
>>> 
======== RESTART: /home/ubuntu/Scrivania/proveStroBlog/provaatan2.py ========
arctan(x) for x varying from 0° to 360° step 30°

x              atan(sin(x)/cos(x))     atan2(sin(x),cos(x))
 30.000               30.000               30.000
 60.000               60.000               60.000
 90.000               90.000               90.000
120.000              -60.000              120.000
150.000              -30.000              150.000
180.000               -0.000              180.000
210.000               30.000             -150.000
240.000               60.000             -120.000
270.000               90.000              -90.000
300.000              -60.000              -60.000
330.000              -30.000              -30.000
360.000               -0.000               -0.000
>>> 

Ecco le prime funzioni goniometriche in gradi e una funzione per riportare un angolo all'angolo giro fondamentale che toglie il segno meno se presente:

import math

def sin(x):
        return math.sin(math.radians(x))

def cos(x):
 return math.cos(math.radians(x))

def tan(x):
        return sin(x)/cos(x)

def atan(x):
        return math.degrees(math.atan(x))

def atan2(y , x):
 return math.degrees(math.atan2(y, x))

def reduce360(x):
 return x % 360.0

Ora ci servono due funzioni per convertire un angolo dalla notazione sessagesimale alla decimale e viceversa. Decido che il segno che compare davanti alle ore darà il segno a tutta la variable decimale, mentre, al contrario, nella conversione da decimale a sessagesimale solo le ore riceveranno un eventuale segno negativo. La funzione, oltre che alle ore, puo' applicarsi immodificata anche agli angoli, sempre in notazione sessagesimale.

def dms2ddd(hour, minute, second):
    """ from sexagesimal to decimal
        the sign of hour variable is automatically applied to minutes and seconds
    """
    if hour < 0:
        sign = -1
        hour *= sign
    else:
        sign = 1
    return (hour+minute/60.0+second/3600.0)*sign

def ddd2dms(dec_hour):
    """ from decimal to sexagesimal representation of hours and angles.
        the sign of dec_hour variable is applied only to hours variable
        see the dms2ddd function for comparison
    """
    if dec_hour < 0:
        sign = -1
        dec_hour *= sign
    else:
        sign = 1
    total_seconds = int(dec_hour * 3600.0+.5)
    seconds = total_seconds % 60 
    total_minutes = int((total_seconds - seconds)/60.0)
    minutes = total_minutes % 60 
    hours = int((total_minutes - minutes)/60.0)
    return (hours * sign, minutes, seconds)

Ci serve inoltre una funzione che converta una data dal formato giorno, mese, anno, ora minuto e secondo, scomodissimo per il calcolo, in quella comoda notazione che corrisponde alla data juliana.

def cal2jul(year, month, day, hour=0, minute=0, second=0):
    """ converts calendar date to julian date
        this routine and the following are built following Duffet Smith /Zwart instructions
        as given in Peter Duffett-Smith-Zwart Practical Astronomy with your Calculator or Spreadsheet
        Fourth Edition, Cambridge University Press, Fourth Ed. 2011
        For an easier use of the function, hours minutes and seconds are defaulted to 0, so it's
        not necessary to give them as parameters when the hour is 00:00:00 
    """
    month2 = month
    year2 = year
    if month2 <= 2:
        year2 -= 1
        month2 += 12
    else:
        pass
    if (year*10000 + month*100 + day) >= 15821015:
        a = math.trunc(year2/100.0)
        b = 2 - a + math.trunc(a/4.0)
    else:
        a = 0
        b = 0
    if year < 0:
        c = math.trunc((365.25 * year2)-0.75)
    else:
        c = math.trunc(365.25 * year2)
    d = math.trunc(30.6001 *(month2 + 1))
    return b + c + d + day + hour / 24.0 + minute / 1440.0 + second / 86400.0 + 1720994.5

Infine ecco due funzioni che servono per il calcolo del tempo siderale di Greenwich e del tempo siderale locale, necessari ad allineare il tempo locale con un riferimento alle cosiddette "stelle fisse" (che tanto fisse non sono, ma per noi astrologi il riferimento statico è l'eclittica e la sua divisione in segni zodiacali, che, per inciso, non c'entrano niente con le costellazioni).

def ut2gst(year, month, day, hour, minute, second):
    """ Sidereal time is a time-keeping system astronomers use to keep track of the direction to point
        their telescopes to view a given star in the night sky.
        Briefly, sidereal time is a "time scale that is based on the Earth's rate of rotation measured
        relative to the fixed stars." (source Wikipedia)
        This routine converts Universal Time to Sidereal Time for Greenwich (Greenwich Sidereal Time)
    """
    jd = cal2jul(year, month, day)
    S = jd - 2451545.0
    T = S/36525.0
    T0 = (6.697374558 + 2400.051336 * T+ 0.000025862 *T*T) % 24
    UT = dms2ddd(hour, minute, second)*1.002737909
    GST = (UT + T0) % 24
    return GST

e

def gst2lst( gst, long_degree, long_minute, long_second=0):
    """ Corrects GST for a different location on the Earth
    """
    lg = dms2ddd(long_degree, long_minute, long_second)/15.
    lst = (gst + lg) % 24.
    return lst

Nel prossimo post vedremo qual è il significato di queste due ultime funzioni.

No comments:

Post a Comment

How to create a virtual linux machine with qemu under Debian or Ubuntu with near native graphics performance

It's been a long time since my latest post. I know, I'm lazy. But every now and then I like to publish something that other people c...