//=========================
function get(formk,frase){
//=========================
// controlla se il campo formk contiene un valore float corretto
// altrimenti emette il messaggio di errore <frase> 
// Restituisce il valore richiesto, dopo averlo convertito in float
// altrimenti restituisce null
// es.: get(this.document.form[0].campo1, "errore nel campo 1")
var L1;

/*
if (formk.value=="") L1=0;
if (formk.value=="-") L1=0;
if (formk.value=="+") L1=0;
if (formk.value==".") L1=0;
*/
if ((formk.value=="")||(formk.value=="-")||(formk.value=="+")||(formk.value==".")) L1=0;
else L1= parseFloat(formk.value); 
if (isNaN(L1)) 
 {alert(frase);
  formk.focus();
  return null;
 } 
return L1;  
} 

//=========================
function getp(formk,frase){
//=========================
// controlla come get(...) in più pretende solo valori positivi
var L1;
L1=get(formk,frase);
if (L1<0)
 {alert("è richiesto un valore positivo!");
  formk.focus();
  return null;
 } 
return L1;  
} 


//===================
function sing(g) {
//===================
// seno con argomento in gradi
return Math.sin(g*Math.PI/180)
}

//===================
function cosg(g) {
//===================
// coseno con argomento in gradi
return Math.cos(g*Math.PI/180)
}

//===================
function tang(g) {
//===================
// tangente con argomento in gradi
return Math.tan(g*Math.PI/180)
}

//====================
function atang(t){
//====================
// restituisce l'angolo in gradi senza correzione di quadrante
return Math.atan(t)*180/Math.PI
}

//====================
function atangq(n,d){
//====================
// restituisce l'angolo in gradi dati il numeratore n 
// e il denominatore d
// con correzione del quadrante corretto
var at=atang(n/d);
if (d<0) return at+180;
else return at;
}

//==================
function  asing(s){
//==================
// arcoseno in gradi, dato il seno
return Math.asin(s)*180/Math.PI;
}

//==================
function  acosg(s){
//==================
// arcocoseno in gradi, dato il coseno
return Math.acos(s)*180/Math.PI;
}
//====================================================
function giornoDecimale(giorno,ora,minuti,secondi){
//====================================================
// ritorna il giorno decimale
return giorno+ora/24+minuti/(24*60)+secondi/(24*3600);
}


//======================================
function decimaleToData(g){
//======================================
 

}
//=====================================
function compattaData(anno,mese,giorno)
//===================================== 
// trasforma la data in un numero decimale di formato YYYY.MMDDdd
// utile per poterlo confrontare con altre date
{
return anno+mese/100+giorno/10000;
}

//=====================================
function p_int(r) 
//=====================================
//ritorna la parte intera di un numero
// es. -7,4 -> -7
{
if (r>0) return Math.floor(r);
if (r<0) return Math.ceil(r);
return 0;
}

//=======================================
function JD(anno,mese,giorno)
//=======================================
// dato un anno, mese, giorno, restituisce il giorno giuliano
// USA compattaData()  e p_int()
{
 var j=0.0;
 var a=0.0;
 var b=0.0;
 var k=.0;
 if (mese<3) {
  --anno;
  mese+=12;
 }
 k=compattaData(anno,mese,giorno);
 if (k>=1582.1015){
  a=p_int(anno/100);
  b=2-a+p_int(a/4);
 }
 
 j= giorno + b - 1524.5 + p_int(365.25*(anno+4716)) + p_int(30.6001*(mese+1));
 
 return j;
}

//===========================================
function SG(jd)
//===========================================
 //dato il giorno giuliano ritorna il secolo giuliano
{
return (jd-2415020.0)/36525;
}

//======================
function dataObj(anno,mese,giorno,ora,minuti,secondi){
this.anno=anno;
this.mese=mese;
this.giorno=giorno;
this.ora=ora;
this.minuti=minuti;
this.secondi=secondi;
}

//======================
function dataDaJD(jd){
//======================
//restituisce la data in oggetto dataObj(anno,mese,giornodecimale), partendo dal giorno giuliano
var A,Z;
var F;
var alfa;
var B,C,D,E;
var d= new dataObj(0,0,0);
jd+=0.5;
Z=p_int(jd);
F=jd-Z;
if (Z<229161) {A=Z}
else{
 alfa=p_int((Z-1867216.25)/36524.25);
 A=Z+1+alfa-p_int(alfa/4);
 }
B=A+1524;
C=p_int((B-122.1)/365.25);
D=p_int(365.25*C);
E=p_int((B-D)/30.6001);
d.giorno=B-D-p_int(30.6001*E)+F;
d.ora=(d.giorno-p_int(d.giorno))*24;
d.minuti=(d.ora-p_int(d.ora))*60;
d.secondi=(d.minuti-p_int(d.minuti))*60;
d.giorno=p_int(d.giorno);
d.minuti=p_int(d.minuti);
d.secondi=p_int(d.secondi);

if (E<13.5) {d.mese=E-1}
else {d.mese=E-13}
if (d.mese>2.5) {d.anno=C-4716}
else {d.anno=C-4715}

return d
}
//===================
function normalizzaGradi1(g) {
//===================
// riduce i valori maggiori di 360° senza corregge i segni negativi
return g%360;
}

//===================
function normalizzaGradi2(g) {
//===================
// riduce i valori maggiori di 360° e corregge i segni negativi
g=g%360;
if (g<0) return g+360;
else return g 
}

//===================
function normalizzaOre1(g) {
//===================
// riduce i valori maggiori di 24 senza corregge i segni negativi
return g%24;
}

//===================
function normalizzaOre2(g) {
//===================
// riduce i valori maggiori di 24 e corregge i segni negativi
g= g%24;
if (g<0) return g+24;
else return g;
}

//=======================
function primi(g){
//=======================
//di un valore in gradi e decimali, restituisce i primi interi
g=Math.abs(g);
return p_int((g-p_int(g))*60)
}

//=======================
function secondi(g){
//=======================
//di un valore in gradi e decimali, restituisce i secondi
g=Math.abs(g);
return ((g-p_int(g))*60-primi(g))*60;
}

//=================
function pot(a,b){
//=================
//restituisce la potenza di una base a elevata ad un esponente intero b
var k;
var ris=a;
if (b==0) return 1;
for (k=2;k<=b;k++) ris=ris*a;
return ris;
}

//***************************************
function displayGradi( g , f1, f2, f3, decimali) {
//***************************************
// dato un valore g in gradi e decimali normalizzato
// oppure ore e decimali normalizzato
// lo mostra in gradi, primi e secondi 
// nelle tre finestre di testo f1,f2,f3
// i secondi vengono mostrati con un  certo numero di decimali
// funziona anche per ore, minuti, secondi
f1.value=String(p_int(g));
f2.value=String(primi(g));
decimali=pot(10,decimali);
f3.value=String(p_int(secondi(g)*decimali)/decimali);
}
//***************************************
function displayGradi3( g , segno, f1, f2, f3, decimali) {
//come sopra ma con la correzione del segno nel caso di valori tipo 0° 34' 29"
//aggiungo il campo segno

if (g>0) {gr= Math.floor(g);segno.value="+"}
else if (g<0) {gr= Math.ceil(g); segno.value="-"; gr=Math.abs(gr)}
else gr= 0;

f1.value=String(gr);
f2.value=String(primi(g));
decimali=pot(10,decimali);
f3.value=String(p_int(secondi(g)*decimali)/decimali);
}

function displayGradi2( g , segno, f1, f2) {
//come sopra ma  tipo 0° 34'
//(nessun campo secondi)

if (g>0) {gr= Math.floor(g);segno.value="+"}
else if (g<0) {gr= Math.ceil(g); segno.value="-"; gr=Math.abs(gr)}
else gr= 0;

f1.value=String(gr);
f2.value=String(primi(g));
//decimali=pot(10,decimali);
//f3.value=String(p_int(secondi(g)*decimali)/decimali);
}


//====================
function dispVal(formk,val,decimali){
var dec=pot(10,decimali);

formk.value=String(p_int(val*dec)/dec);
}

//============================
function gradiDec(gradi, primi, secondi){
//============================
//converte in gradi decimali
var gtemp=Math.abs(gradi) + primi/60 + secondi/3600;
if (gradi<0) return -gtemp;
else return gtemp;
}

//====================================================
function giornoDecimale(giorno,ora,minuti,secondi){
//====================================================
// ritorna il giorno decimale
return giorno+ora/24+minuti/(24*60)+secondi/(24*3600);
}


//*******************************************
// coordinate geografiche e geocentriche
//*******************************************

//===================================
function latGeocentrica(fi){
//===================================
//restituisce la latitudine geocentrica, data la lat. geografica fi
return atang(0.99664719*0.99664719*tang(fi));
}

//================================
function roSinFiPrimo(fi,H){ 
//================================
// restituisce ro sin fiprimo data la latitudine geografica fi
// e l'altezza slm H in metri
var u;
u=Math.atan(0.99664719*tang(fi));
return 0.99664719*Math.sin(u)+sing(fi)*H/6378140;
}

//================================
function roCosFiPrimo(fi,H){ 
//================================
// restituisce ro cos fiprimo data la latitudine geografica fi
// e l'altezza slm H in metri
var u;
u=Math.atan(0.99664719*tang(fi));
return Math.cos(u)+cosg(fi)*H/6378140;
}

//===========
function ro(fi,H){
//===========
//restituisce la distanza di un  punto dal centro della terra, data la lat.geografica fi
//e l'altezza slm H in metri
return roSinFiPrimo(fi,H)/cosg(latGeocentrica(fi));
}

//=====================
function deltaT(sg){
//=====================
// Tempo delle Effemeridi meno Tempo Universale, approssimato,
// in minuti,
// dato il tempo sg in secoli giuliani dal 1900
return 0.41+1.2053*sg+0.4992*sg*sg;
}

//======================
function JDET(jd){
//======================
// restituisce il Tempo delle Effemeridi, approssimato
// in giorni giuliani, dato il TU in giorni giuliani
// questo valore dovrebbe sostituire il semplice JD() prima del calcolo
// preciso delle effemeridi
return jd+deltaT(SG(jd))/(24*60);
}

//===================================================
function tempoSideraleMedioGreenw(anno,mese,giorno,ora,minuto,secondo){
//===================================================
// dal tempo UT ritorna il tempo siderale medio a Greenwich
//?zero
// per maggior precisione, va corretta 
// con	l'aggiunta della nutazione in ascensione retta espressa 
// in secondi di tempo (?? cos ?/15)
var jdZero;
var sg;
var ts;
 jdZero=JD(anno,mese,giorno);
//giorno giuliano a 0h UT
sg=SG(jdZero);
ts=0.276919398+100.0021359*sg+0.000001075*sg*sg;
// tempo siderale in rivoluzioni
ts= (ts-p_int(ts))*24; //in ore
ts= ts+(ora+minuto/60+secondo/3600)*1.002737908;
ts=ts%24;
if (ts<0) ts=ts+24;
return ts;
// tempo siderale in ore
}

//===================================================
function tempoSideraleApparenteGreenw(anno,mese,giorno,ora,minuto,secondo){
//===================================================
// con	l'aggiunta della nutazione in ascensione retta espressa 
// in secondi di tempo 
var jd;
var sg;
jd= JD(anno,mese,giornoDecimale(giorno, ora,minuto,secondo));
sg= SG(jd);
var correzione =(deltaPsi(sg)*cosg(obliquitaEclittica(sg)))/(15*3600);
return tempoSideraleMedioGreenw(anno,mese,giorno,ora,minuto,secondo)+correzione;
// tempo siderale in ore
}

//********************************************
// CONVERSIONE DI COORDINATE
//********************************************

//===========================
function tempoSideraleLocale(tsgr,longit){
//===========================
// dati tsgr -> tempo siderale a Greenwich (medio o apparente) in ore e decimali
// e long -> la longitudine del luogo di osservazione in gradi e decimali
// negativa a EST e positiva a OVEST
// ritorna il tempo Siderale locale (medio o apparente) in  ore e decimali
return tsgr - longit/15;
}

//=============================
function angoloOrarioLocale(tsloc,AR){
//=============================
// restituisce l'angolo orario locale di un oggetto
// con Ascensione Retta AR in ore e decimali
// conoscendo il tempo siderale locale tsloc (in ore e decimali)
// NB: se AR è affetto da nutazione, anche tsloc lo deve essere!!!!
return tsloc - AR;
}

// ALTEZZA 
function altezza(lat,long,ar,dec,anno,mese,giorno,ora,minuti,secondi){
//ar in ore
var tsa=tempoSideraleApparenteGreenw(anno,mese,giorno,ora,minuti,secondi);
var tsal=tempoSideraleLocale(tsa,long);
var H=(tsal-ar)*15;
return asing(sing(lat)*sing(dec)+cosg(lat)*cosg(dec)*cosg(H));
}

// AZIMUT 
function azimut(lat,long,ar,dec,anno,mese,giorno,ora,minuti,secondi){
//var sg=SG(JD(anno,mese,giornoDecimale(giorno,ora,minuti,secondi)));
//var epsylon=obliquitaEclittica(sg)+deltaEpsylon(sg);//per l'uso di coordinate vere (vedi p.39)
var tsa=tempoSideraleApparenteGreenw(anno,mese,giorno,ora,minuti,secondi);
var tsal=tempoSideraleLocale(tsa,long);
var H=(tsal-ar)*15;
return atangq(sing(H),cosg(H)*sing(lat)-tang(dec)*cosg(lat));
}

function subf1 (a,d,e){
return atangq(sing(a)*cosg(e)+tang(d)*sing(e),cosg(a));
}

function subf2(a,d,e){
return asing(sing(d)*cosg(e)-cosg(d)*sing(e)*sing(a));
}

//===============================
function ARToLongEcl(AR,decl,epsylon){
//===============================
// trasforma l'ascensione retta AR (coord. equatoriale) espressa in h e dec
// in longitudine eclittica lambda (coord. eclitticale) in gradi e decimali
// conoscendo epsylon (obliquità dell'eclittica) in gradi
// e decl (declinazione delta) in gradi (coord. equatoriale)
AR=AR*15; //trasforma in gradi
return subf1(AR,decl,epsylon);
}

//==============================
function  declToBeta(AR,decl,epsylon){
//==============================
// dato AR in ore, declinazione equatoriale e obliquità dell'eclittica,
// restituisce latitudine eclittica (beta)
AR=AR*15;
return subf2(AR,decl,epsylon); 
}

//=========================================
function longToAR(lambda,beta,epsylon){
//========================================
//date le coordinate eclittiche lambda e beta in gradi e obliquità epsylon, restituisce AR
return subf1(lambda,beta,epsylon);
}


//=====================================
function compattaData(anno,mese,giorno)
//===================================== 
// trasforma la data in un numero decimale di formato YYYY.MMDDdd
// utile per poterlo confrontare con altre date
{
return anno+mese/100+giorno/10000;
}

//=======================================
function JD(anno,mese,giorno)
//=======================================
// dato un anno, mese, giorno, restituisce il giorno giuliano
// USA compattaData()  e p_int()
{
 var j=0.0;
 var a=0.0;
 var b=0.0;
 var k=.0;
 if (mese<3) {
  --anno;
  mese+=12;
 }
 k=compattaData(anno,mese,giorno);
 if (k>=1582.1015){
  a=p_int(anno/100);
  b=2-a+p_int(a/4);
 }
 
 j= giorno + b - 1524.5 + p_int(365.25*(anno+4716)) + p_int(30.6001*(mese+1));
 
 return j;
}


function anomaliaEccentrica(e,M,p){
// e=eccentricità dell'orbita del pianeta 
// M = anomalia media in gradi
// p = precisione richiesta
M=M*Math.PI/180; //trasformare in radianti
var E=M;
p=p*Math.PI/180; //adeguamento della precisione
var E1=M+e*Math.sin(E); //valore iniziale
var i=0;
while (Math.abs(E-E1)>p) { //ciclo di approssimazione
   E=E1;
   E1=M+e*Math.sin(E);
   i++;
  }
  //dispVal(this.document.forms[0].prova2,i,3);
return E1*180/Math.PI;	
}


//****************************
// COORDINATE SOLARI
//****************************

function longMediaGeomSole(sg){
// longitudine media geometrica del sole riferita all'equinozio medio della data
return 279.69668+36000.76892*sg+0.0003025*sg*sg;
}

function longMediaGeomSoleJD(jd){
// dall'almanacco 2004 uai
return 279.495818+0.98564736*(jd-2452274.5);
}

function longVeraSole(sg){
var A=153.23+22518.7541*sg;
var B=216.57+45037.5082*sg;
var C=312.69+32964.3577*sg;
var D=350.74+445267.1142*sg-0.00144*sg*sg;
var E=231.19+20.20*sg;
var add=0.00134*cosg(A)+0.00154*cosg(B)+0.00200*cosg(C)+0.00179*sing(D)+0.00178*sing(E);
return longMediaGeomSole(sg)+equazioneCentroSole(sg)+add

}


function longApparenteSoleEqVero(sg){
// longitudine apparente del Sole all'equinozio vero della data
return longVeraSole(sg)-0.00569-0.00479*sing(sigma(sg))
}

function anomaliaMediaSole(sg){
return 358.475833+35999.04975*sg-0.000150*sg*sg-0.0000033*sg*sg*sg;
}

function anomaliaMediaSoleJD(jd){
return 356.523130+0.98560028*(jd-2452274.5);
}

function anomaliaMediaSole2(sg){
// più termine additivo di 1782 anni
return anomaliaMediaSole(sg)-0.001778*sing(51.2+20.2*sg)
}


function equazioneCentroSole(sg){
var M=anomaliaMediaSole(sg);
return (1.919460-0.004789*sg-0.000014*sg*sg)*sing(M)+(0.020094-0.000100*sg)*sing(2*M)+0.000293*sing(3*M)
}


function anomaliaVeraSole(sg){
return anomaliaMediaSole(sg)+equazioneCentroSole(sg)
}

function raggioVettoreSole(sg){
var e=eccentricitaTerra(sg);
var A=153.23+22518.7541*sg;
var B=216.57+45037.5082*sg;
var C=312.69+32964.3577*sg;
var D=350.74+445267.1142*sg-0.00144*sg*sg;
var H=353.40+65928.7155*sg;
var add=0.00000543*sing(A)+0.00001575*sing(B)+0.00001627*sing(C)+0.00003076*cosg(D)+0.00000927*sing(H);
return 1.0000002*(1-e*e)/(1+e*cosg(anomaliaVeraSole(sg)))+add
}

function ARVeraSole(sg){
// Ascensione retta della posizione vera del Sole
return atangq(cosg(obliquitaEclittica(sg))*sing(longVeraSole(sg)),cosg(longVeraSole(sg))); 
}

function ARAppSole(sg){
// Ascensione retta della posizione vera del Sole
//return atangq(cosg(obliquitaEclittica2(sg))*sing(longVeraSole(sg)),cosg(longVeraSole(sg)));  
return atangq(cosg(obliquitaEclittica2(sg))*sing(longApparenteSoleEqVero(sg)),cosg(longApparenteSoleEqVero(sg)));  
}

function declinazioneVeraSole(sg){
return asing(sing(obliquitaEclittica(sg))*sing(longVeraSole(sg)))
}

function declinazioneAppSole(sg){
//return asing(sing(obliquitaEclittica2(sg))*sing(longVeraSole(sg)))
return asing(sing(obliquitaEclittica2(sg))*sing(longApparenteSoleEqVero(sg)))
}


function eqTempo(sg){
var epsylon=obliquitaEclittica(sg);
var L=longMediaGeomSole(sg);
var e=eccentricitaTerra(sg);
var M=anomaliaMediaSole(sg);
var y = tang(epsylon/2)*tang(epsylon/2);
return (((-(y*sing(2*L)-2*e*sing(M)+4*e*y*sing(M)*cosg(2*L)-.5*y*y*sing(4*L)-(5/4)*e*e*sing(2*M)))*180/Math.PI)%360)/15;
}
function eqTempoJD(jd){
var epsylon=obliquitaEclitticaJD(jd);
var L=longMediaGeomSoleJD(jd);
var e=eccentricitaTerraJD(jd);
var M=anomaliaMediaSoleJD(jd);
var y = tang(epsylon/2)*tang(epsylon/2);
return (((-(y*sing(2*L)-2*e*sing(M)+4*e*y*sing(M)*cosg(2*L)-.5*y*y*sing(4*L)-(5/4)*e*e*sing(2*M)))*180/Math.PI)%360)/15;
}

function transitoSoleMeridianoFuso(sg, Z, hlegale){
// Z numero intero di timezone (da noi -1)
// hlegale 0 o 1 (ora legale estiva no o si)
}
function transitoSoleLuogo(sg, longitgeo,Z,hlegale){
// Z numero intero di timezone (da noi -1)
// hlegale 0 o 1 (ora legale estiva no o si)
// longitgeo: longitudine geografica del luogo in gradi
return 12+eqTempo(sg)+longitgeo/15-Z+hlegale
}

function transitoSoleLuogoJD(jd, longitgeo,Z,hlegale){
// Z numero intero di timezone (da noi -1)
// hlegale 0 o 1 (ora legale estiva no o si)
// longitgeo: longitudine geografica del luogo in gradi
return 12+eqTempoJD(jd)+longitgeo/15-Z+hlegale
}

//********************************
// TERRA
//********************************

function eccentricitaTerra(sg){
return 0.01675104-0.0000418*sg-0.000000126*sg*sg
}

function eccentricitaTerraJD(jd){
return 0.01670748-0.0000000012*(jd-2452274.5);
}


function obliquitaEclittica(sg){
return 23.452294-0.0130125*sg-0.00000164*sg*sg+0.000000503*sg*sg*sg
}
function obliquitaEclittica2(sg){
return obliquitaEclittica(sg)+0.00256*cosg(sigma(sg))
}

function obliquitaEclitticaJD(jd){
return 23.439031-0.00000036*(jd-2452274.5);
}

function deltaPsi(sg){
// Nutazione in longitudine espressa in secondi
var L=longMediaGeomSole(sg);
var L1=longMediaLuna(sg);
var M=anomaliaMediaSole(sg);
var M1=anomaliaMediaLuna(sg);
var S=sigma(sg);
return -(17.2327+0.01737*sg)*sing(S)
	   -(1.2729+0.00013*sg)*sing(2*L)
	   +0.2088*sing(2*S)
	   -0.2037*sing(2*L1)
	   +(0.1261-0.00031*sg)*sing(M)
	   +0.0675*sing(M1)
	   -(0.0497-0.00012*sg)*sing(2*L+M)
	   -0.0342*sing(2*L1-S)
	   -0.0261*sing(2*L1+M1)
	   +0.0214*sing(2*L-M)
	   -0.0149*sing(2*L-2*L1+M1)
	   +0.0124*sing(2*L-S)
	   +0.0114*sing(2*L1-M1)	
}

function deltaEpsylon(sg){
//Nutazione in obliquità espressa in secondi
var L=longMediaGeomSole(sg);
var L1=longMediaLuna(sg);
var M=anomaliaMediaSole(sg);
var M1=anomaliaMediaLuna(sg);
var S=sigma(sg);
return +(9.2100+0.00091*sg)*cosg(S)
	   +(0.5522-0.00029*sg)*cosg(2*L)
	   -0.0904*cosg(2*S)
	   +0.0884*cosg(2*L1)
	   +0.0216*cosg(2*L+M)
	   +0.0183*cosg(2*L1-S)
	   +0.0113*cosg(2*L1+M1)
	   -0.0093*cosg(2*L-M)
	   -0.0066*cosg(2*L-S)
}






//********************
// LUNA
//*******************
function sigma(sg){
//Longitudine del nodo ascendente
 return normalizzaGradi2( 259.183275-1934.1420*sg+0.002078*sg*sg+0.0000022*sg*sg*sg);
}

function longMediaLuna(sg){
//L1
return 270.434164+481267.8831*sg-0.001133*sg*sg+0.0000019*sg*sg*sg 
}

function longMediaLuna2(sg){
//L1 + termine additivo di 1782 anni
var L= longMediaLuna(sg)+0.000233*sing(51.2+20.2*sg)
	+0.003964*sing(346.560+132.870*sg-0.0091731*sg*sg) //grande termine di Venere di 271 anni
	+0.001964*sing(sigma(sg));
return normalizzaGradi2(L);	
}

function anomaliaMediaLuna(sg){
//M1
return normalizzaGradi2(296.104608+477198.8491*sg+0.009192*sg*sg+0.0000144*sg*sg*sg)
}

function anomaliaMediaLuna2(sg){
//M1 + termine additivo di 1782 anni
return anomaliaMediaLuna(sg)+0.000817*sing(51.2+20.2*sg)
		+0.003964*sing(346.560+132.870*sg-0.0091731*sg*sg) //grande termine di Venere di 271 anni
		+0.002541*sing(sigma(sg))
}

function elongazioneMediaLuna(sg){
//D
return normalizzaGradi2(350.737486+445267.1142*sg-0.001436*sg*sg+0.0000019*sg*sg*sg)
}

function elongazioneMediaLuna2(sg){
//D + termine additivo di 1782 anni
return elongazioneMediaLuna(sg)+0.002011*sing(51.2+20.2*sg)
	+0.003964*sing(346.560+132.870*sg-0.0091731*sg*sg) //grande termine di Venere di 271 anni
	+0.001964*sing(sigma(sg))
}

function distanzaMediaDalNodoAscendenteLuna(sg){
//F
return 11.250889+483202.0251*sg-0.003211*sg*sg-0.0000003*sg*sg*sg
}

function distanzaMediaDalNodoAscendenteLuna2(sg){
//F
var s=sigma(sg);
var d= 11.250889+483202.0251*sg-0.003211*sg*sg-0.0000003*sg*sg*sg
	+0.003964*sing(346.560+132.870*sg-0.0091731*sg*sg) //grande termine di Venere di 271 anni
	-0.024691*sing(s)
	-0.004328*sing(s+275.05-2.30*sg);
return normalizzaGradi2(d)
}

//********************************
function longitudineGeocLuna(sg){
//********************************
// longitudine geocentrica della luna
var L1=longMediaLuna2(sg);
var m1=anomaliaMediaLuna2(sg);
var d=elongazioneMediaLuna2(sg);
var m=anomaliaMediaSole2(sg);
var f=distanzaMediaDalNodoAscendenteLuna2(sg);
var e=1-0.002495*sg-0.00000752*sg*sg;
var e2=e*e;
var lvera=
	L1+6.288750*sing(m1) //1
		+1.274018*sing(2*d-m1) //2
		+0.658309*sing(2*d) //3
		+0.213616*sing(2*m1) //4
		-e*0.185596*sing(m) //5
		-0.114336*sing(2*f)//6
		+0.058793*sing(2*d-2*m1) //7
		+e*0.057212*sing(2*d-m-m1)
		+0.053320*sing(2*d+m1)
		+e*0.045874*sing(2*d-m)//10
		+e*0.041024*sing(m1-m)
		-0.034718*sing(d)
		-e*0.030465*sing(m+m1)
		+0.015326*sing(2*d-2*f)
		-0.012528*sing(2*f+m1)//15
		-0.010980*sing(2*f-m1)
		+0.010674*sing(4*d-m1)
		+0.010034*sing(3*m1)
		+0.008548*sing(4*d-2*m1)
		-e*0.007910*sing(m-m1+2*d)//20
		-e*0.006783*sing(2*d+m)
		+0.005162*sing(m1-d)
		+e*0.005000*sing(m+d)
		+e*0.004049*sing(m1-m+2*d)//24
		+0.003996*sing(2*m1+2*d)//25
		+0.003862*sing(4*d)
		+0.003665*sing(2*d-3*m1)
		+e*0.002695*sing(2*m1-m)
		+0.002602*sing(m1-2*f-2*d)
		+e*0.002396*sing(2*d-m-2*m1)//30
		-0.002349*sing(m1+d)
		+e2*0.002249*sing(2*d-2*m)
		-e*0.002125*sing(2*m1+m)
		-e2*0.002079*sing(2*m)
		+e2*0.002059*sing(2*d-m1-2*m)//35
		-0.001773*sing(m1+2*d-2*f)
		-0.001595*sing(2*f+2*d)
		+e*0.001220*sing(4*d-m-m1)
		-0.001110*sing(2*m1+2*f)
		+0.000892*sing(m1-3*d)//40
		-e*0.000811*sing(m+m1+2*d)
		+e*0.000761*sing(4*d-m-2*m1)
		+e2*0.000717*sing(m1-2*m)
		+e2*0.000704*sing(m1-2*m-2*d)
		+e*0.000693*sing(m-2*m1+2*d)//45
		+e*0.000598*sing(2*d-m-2*f)
		+0.000550*sing(m1+4*d)
		+0.000538*sing(4*m1)
		+e*0.000521*sing(4*d-m)
		+0.000486*sing(2*m1-d);
return normalizzaGradi2(lvera)		
}

//*******************************
function latitudineGeocLuna(sg){
//*******************************
// latitudine geocentrica Luna
var L1=longMediaLuna2(sg);
var m1=anomaliaMediaLuna2(sg);
var d=elongazioneMediaLuna2(sg);
var m=anomaliaMediaSole2(sg);
var f=distanzaMediaDalNodoAscendenteLuna2(sg);
var e=1-0.002495*sg-0.00000752*sg*sg;
var e2=e*e;
var B= 5.128189*sing(f)
	+0.280606*sing(m1+f)
	+0.277693*sing(m1-f)
	+0.173238*sing(2*d-f)
	+0.055413*sing(2*d+f-m1)//5
	+0.046272*sing(2*d-f-m1)
	+0.032573*sing(2*d+f)
	+0.017198*sing(2*m1+f)
	+0.009267*sing(2*d+m1-f)
	+0.008823*sing(2*m1-f)//10
	+e*0.008247*sing(2*d-m-f)
	+0.004323*sing(2*d-f-2*m1)
	+0.004200*sing(2*d+f+m1)
	+e*0.003372*sing(f-m-2*d)
	+e*0.002472*sing(2*d+f-m-m1)//15
	+e*0.002222*sing(2*d+f-m)
	+e*0.002072*sing(2*d-f-m-m1)
	+e*0.001877*sing(f-m+m1)
	+0.001828*sing(4*d-f-m1)
	-e*0.001803*sing(f+m)//20
	-0.001750*sing(3*f)
	+e*0.001570*sing(m1-m-f)
	-0.001487*sing(f+d)
	-e*0.001481*sing(f+m+m1)
	+e*0.001417*sing(f-m-m1)	//25
	+e*0.001350*sing(f-m)
	+0.001330*sing(f-d)
	+0.001106*sing(f+3*m1)
	+0.001020*sing(4*d-f)
	+0.000833*sing(f+4*d-m1)//30
	+0.000781*sing(m1-3*f)
	+0.000670*sing(f+4*d-2*m1)
	+0.000606*sing(2*d-3*f)
	+0.000597*sing(2*d+2*m1-f)
	+e*0.000492*sing(2*d+m1-m-f)//35
	+0.000450*sing(2*m1-f-2*d)
	+0.000439*sing(3*m1-f)
	+0.000423*sing(f+2*d+2*m1)
	+0.000422*sing(2*d-f-3*m1)
	-e*0.000367*sing(m+f+2*d-m1)//40
	-e*0.000353*sing(m+f+2*d)
	+0.000331*sing(f+4*d)
	+e*0.000317*sing(2*d+f-m+m1)
	+e2*0.000306*sing(2*d-2*m-f)
	-0.000283*sing(m1+3*f);
var s=sigma(sg);	
var omega1=0.0004664*cosg(s);
var omega2=0.0000754*cosg(s+275.05-2.30*sg);
return B*(1-omega1-omega2)	
}

//**********************
function parallasseOrizzLuna(sg){
//pigreco
var L1=longMediaLuna2(sg);
var m1=anomaliaMediaLuna2(sg);
var d=elongazioneMediaLuna2(sg);
var m=anomaliaMediaSole2(sg);
var f=distanzaMediaDalNodoAscendenteLuna2(sg);
var e=1-0.002495*sg-0.00000752*sg*sg;
var e2=e*e;
return +0.950724
		+0.051818*cosg(m1)
		+0.009531*cosg(2*d-m1)
		+0.007843*cosg(2*d)
		+0.002824*cosg(2*m1)//5
		+0.000857*cosg(2*d+m1)
		+e*0.000533*cosg(2*d-m)
		+e*0.000401*cosg(2*d-m-m1)
		+e*0.000320*cosg(m1-m)
		-0.000271*cosg(d)//10
		-e*0.000264*cosg(m+m1)
		-0.000198*cosg(2*f-m1)
		+0.000173*cosg(3*m1)
		+0.000167*cosg(4*d-m1)
		-e*0.000111*cosg(m)//15
		+0.000103*cosg(4*d-2*m1)
		-0.000084*cosg(2*m1-2*d)
		-e*0.000083*cosg(2*d+m)
		+0.000079*cosg(2*d+2*m1)
		+0.000072*cosg(4*d)//20
		+e*0.000064*cosg(2*d-m+m1)
		-e*0.000063*cosg(2*d+m-m1)
		+e*0.000041*cosg(m+d)
		+e*0.000035*cosg(2*m1-m)
		-0.000033*cosg(3*m1-2*d)//25
		-0.000030*cosg(m1+d)
		-0.000029*cosg(2*f-2*d)
		-e*0.000029*cosg(2*m1+m)
		+e2*0.000026*cosg(2*d-2*m)
		-0.000023*cosg(2*f-2*d+m1)//30
		+0.000019*cosg(4*d-m-m1)		
}

function distanzaCentriLunaTerra(sg){
//in km
return 6378.14/sing(parallasseOrizzLuna(sg))
}

//=========================
function ARVeraLuna(sg){
//=========================
// Ascensione Retta in h m s
var e=obliquitaEclittica(sg);
var l=longitudineGeocLuna(sg);
var b=latitudineGeocLuna(sg);
return normalizzaGradi2(atangq(sing(l)*cosg(e)-tang(b)*sing(e),cosg(l)))/15
}

//=========================
function ARAppLuna(sg){
//=========================
// Ascensione Retta apparente in h m s
var e=obliquitaEclittica2(sg);
var l=longitudineGeocLuna(sg);
var b=latitudineGeocLuna(sg);
return normalizzaGradi2(atangq(sing(l)*cosg(e)-tang(b)*sing(e),cosg(l)))/15
}

//=========================
function decVeraLuna(sg){
//============================
// declinazione vera
var e=obliquitaEclittica(sg);
var l=longitudineGeocLuna(sg);
var b=latitudineGeocLuna(sg);
return asing(sing(b)*cosg(e)+cosg(b)*sing(e)*sing(l))
}

//=========================
function decAppLuna(sg){
//============================
// declinazione apparente
var e=obliquitaEclittica2(sg);
var l=longitudineGeocLuna(sg);
var b=latitudineGeocLuna(sg);
return asing(sing(b)*cosg(e)+cosg(b)*sing(e)*sing(l))
}

function frazioneIlluminataLuna(sg){
var lvs = longVeraSole(sg);
var L = longitudineGeocLuna(sg);
var B = latitudineGeocLuna(sg);
var d= acosg(cosg(L-lvs)*cosg(B));
var i = 180-d-0.1468*sing(d)*(1-0.0549*sing(anomaliaMediaLuna2(sg)))/(1-0.0167*sing(anomaliaMediaSole2(sg)));
return (1+cosg(i))/2
}

//*************
// PIANETI
//*************

function mer(){
// mercurio
this.L=new Array(178.179078,149474.07078,0.0003011,0);
this.a=0.3870986;
this.e=new Array(0.20561421,0.00002046,-0.000000030,0);
this.i=new Array(7.002881,0.0018608,-0.0000183,0);
this.o=new Array(28.753753,0.3702806,0.0001208,0);
this.s=new Array(47.145944,1.1852083,0.0001739,0);
}


function ven(){
// venere
this.L=new Array(342.767053,58519.21191,0.0003097,0);
this.a=0.7233316;
this.e=new Array(0.00682069,-0.00004774,0.000000091,0);
this.i=new Array(3.393631,0.0010058,-0.0000010,0);
this.o=new Array(54.384186,0.5081861,-0.0013864,0);
this.s=new Array(75.779647,0.8998500,0.0004100,0);
}

function mar(){
// marte
this.L=new Array(293.737334,19141.69551,0.0003107,0);
this.a=1.5236883;
this.e=new Array(0.09331290,0.000092064,-0.000000077,0);
this.i=new Array(1.850333,-0.0006750,0.0000126,0);
this.o=new Array(285.431761,1.0697667,0.0001313,0.00000414);
this.s=new Array(48.786442,0.7709917,-0.0000014,-0.00000533);
}


function gio(){
// giove
this.L=new Array(238.049257,3036.301986,0.0003347,-0.00000165);
this.a=5.202561;
this.e=new Array(0.04833475,0.000164180,-0.0000004676,-0.0000000017);
this.i=new Array(1.308736,-0.0056961,0.0000039,0);
this.o=new Array(273.277558,0.5994317,0.00070405,0.00000508);
this.s=new Array(99.443414,1.0105300,0.00035222,-0.00000851);
}

function sat(){
// saturno
this.L=new Array(266.564377,1223.509884,0.0003245,-0.0000058);
this.a=9.554747;
this.e=new Array(0.05589232,-0.00034550,-0.000000728,0.00000000074);
this.i=new Array(2.492519,-0.0039189,-0.00001549,0.00000004);
this.o=new Array(338.307800,1.0852207,0.00097854,0.00000992);
this.s=new Array(112.790414,0.8731951,-0.00015218,-0.00000531);
}

function ura(){
// urano
this.L=new Array(244.197470,429.863546,0.0003160,-0.00000060);
this.a=19.21814;
this.e=new Array(0.0463444,-0.00002658,0.000000077,0);
this.i=new Array(0.772464,0.0006253,0.0000395,0);
this.o=new Array(98.071581,0.9857650,-0.0010745,-0.00000061);
this.s=new Array(73.477111,0.4986678,0.0013117,0);
}

function net(){
// nettuno
this.L=new Array(84.457994,219.885914,0.0003205,-0.00000060);
this.a=30.10957;
this.e=new Array(0.00899704,0.000006330,-0.000000002,0);
this.i=new Array(1.779242,-0.0095436,-0.0000091,0);
this.o=new Array(276.045975,0.3256394,0.00014095,0.000004113);
this.s=new Array(130.681384,1.0989350,0.00014987,-0.000004718);
}

function polinomio (a,sg){
return a[0]+a[1]*sg+a[2]*sg*sg+a[3]*sg*sg*sg
}

function longitudineMediaP(p,sg){
return normalizzaGradi2(polinomio(p.L,sg))
}

function eccentricitaP(p,sg){
return polinomio(p.e,sg)
}

function inclinazioneP(p,sg){
return polinomio(p.i,sg)
}

function argPerielioP(p,sg){
return polinomio(p.o,sg)
}

function longNodoAscP(p,sg){
return polinomio(p.s,sg)
}

function anomaliaMediaP(p,sg){
return normalizzaGradi2(longitudineMediaP(p,sg)-argPerielioP(p,sg)-longNodoAscP(p,sg));
}

function distanzaPerielicaP(p,sg){
return p.a*(1-eccentricitaP(p,sg))
}

function distanzaAfelicaP(p,sg){
return p.a*(1+eccentricitaP(p,sg))
}


function anomaliaVeraP(p,sg){
var e=eccentricitaP(p,sg);
var E=anomaliaEccentrica(e,anomaliaMediaP(p,sg),0.0000001);
return normalizzaGradi2(atang(Math.sqrt((1+e)/(1-e))*tang(E/2))*2); 
}

function raggioVettoreP(p,sg){
var e=eccentricitaP(p,sg);
return (p.a*(1-e*e))/(1+e*cosg(anomaliaVeraP(p,sg)));
}

function argLatitudineP(p,sg){
return longitudineMediaP(p,sg)+anomaliaVeraP(p,sg)-anomaliaMediaP(p,sg)-longNodoAscP(p,sg)
}

function longitudineEclitticaP(p,sg){
var i=inclinazioneP(p,sg);
var u=argLatitudineP(p,sg);
return atangq(cosg(i)*sing(u),cosg(u))+longNodoAscP(p,sg);
}

function latitudineEclitticaP(p,sg){
return asing(sing(argLatitudineP(p,sg))*sing(inclinazioneP(p,sg)));
}

function  longitudineGeocP(p,sg){
var L=longVeraSole(sg);
var b=latitudineEclitticaP(p,sg);
var R=raggioVettoreSole(sg);
var r=raggioVettoreP(p,sg);
var l=longitudineEclitticaP(p,sg);
var N=r*cosg(b)*sing(l-L);
var D=r*cosg(b)*cosg(l-L)+R;
return normalizzaGradi2(atangq(N,D)+L);
}

function distanzaTerraP(p,sg){
var L=longVeraSole(sg);
var b=latitudineEclitticaP(p,sg);
var R=raggioVettoreSole(sg);
var r=raggioVettoreP(p,sg);
var l=longitudineEclitticaP(p,sg);
var N=r*cosg(b)*sing(l-L);
var D=r*cosg(b)*cosg(l-L)+R;
return Math.sqrt(N*N+D*D+(r*sing(b))*(r*sing(b)))
}

function tempoluce(p,sg){
return 0.0057756*distanzaTerraP(p,sg)
}

function latitudineGeocP(p,sg){
var b=latitudineEclitticaP(p,sg);
var r=raggioVettoreP(p,sg);
var d=distanzaTerraP(p,sg);
return asing(r*sing(b)/d);
}

function elongazioneP(p,sg){
var b=latitudineGeocP(p,sg);
var lambda=longitudineGeocP(p,sg);
var L=longVeraSole(sg);
return acosg(cosg(b)*cosg(lambda-L));
}

function ARP(p,sg){
// restituisce l'ascensione retta del pianeta
var epsylon=obliquitaEclittica(sg);
var lambda=longitudineGeocP(p,sg);
var beta=latitudineGeocP(p,sg);
return normalizzaGradi2(atangq(sing(lambda)*cosg(epsylon)-tang(beta)*sing(epsylon),cosg(lambda)));
//return normalizzaGradi2(longToAR(lambda,beta,epsylon));
}

function declinazione(p,sg){
// restituisce la declinazione equatoriale
var epsylon=obliquitaEclittica(sg);
var lambda=longitudineGeocP(p,sg);
var beta=latitudineGeocP(p,sg);
return asing(sing(beta)*cosg(epsylon)+cosg(beta)*sing(epsylon)*sing(lambda));
}

function a(k){
switch (k) {
 case 1: return 1;
 case 3: return 2;
 case 4: return 3;
  }
}

function costellazione(L){
// L = longitudine geocentrica
L=Math.round(L);
if (L>350.5 || L<28.5) return "Pesci";
if (L>28.5 && L<52.5) return "Ariete";
if (L>52.5 && L<89.5) return "Toro";
if (L>89.5 && L<117.5) return "Gemelli";
if (L>117.5 && L<137.5) return "Cancro";
if (L>137.5 && L<173.5) return "Leone";
if (L>173.5 && L<217.5) return "Vergine";
if (L>217.5 && L<240.5) return "Bilancia";
if (L>240.5 && L<248.5) return "Scorpione";
if (L>248.5 && L<266.5) return "Ofiuco";
if (L>266.5 && L<299.5) return "Sagittario";
if (L>299.5 && L<328.5) return "Capricorno";
if (L>328.5 && L<350.5) return "Aquario";
}


