Sun Calculator Java implementation

Sunrise landscape render retouches

Here's java implementation of Sun Calculator algirthm for scientific work:

Input data description:
- int <b>day</b> - 1 to 31              
- int <b>month</b> - 1 to 12      
- int <b>year</b> - 1900 to XXXX        
- float <b>latitude</b> - -90 to +90
- float <b>longitude</b> - -180 to +180


Output data (massOut) description:
- resolveStr[12] : resolveStr[13] - 1 Astronomical Twilight
- resolveStr[8] : resolveStr[9] - 1 Navigation Twiling
- resolveStr[4] : resolveStr[5] - 1 Social Twilight
- resolveStr[0] : resolveStr[1] - Sunrise
- resolveStr[16] : resolveStr[17] - Semiday
- resolveStr[2] : resolveStr[3] - Sunset
- resolveStr[6] : resolveStr[7] - 2 Social Twilight
- resolveStr[10] : resolveStr[11] - 2 Navigation Twiling
- resolveStr[14] : resolveStr[15] - 2 Astronomical Twilight
- resolveStr[18] h resolveStr[19] m  - Length of Day


 Class:


public class SunTimes {
  
 
 // SunCalc v1.1, 2011
  
 public static boolean err=false;
 
 public int[] getSunTime( int day,                
                    int month,         
                    int year,          
                    float latitude,    //-90 - +90
                    float longitude ){ //-180 - +180
                  
                                       
  float N,lngHour,tRis,tSet,localOffset;
  int[] times=new int[20];
  int[] delta=new int[2];
  
  if(latitude<-90 || latitude>90 || 
     longitude<-180 || longitude>180 || 
     year<1900 || year>3000 ||
     month<1 || month>12 ||
     day<1 || day>31)
     return(times);
  
  //localOffset=(int)longitude/15;
  
  N = getDay(day,month,year);
  lngHour = longitude / 15;

  float[] cos_zen={-0.01454F,-0.10452F,-0.20791F,-0.30902F};
  int i=0,it=0;
  while(it<4){
   tRis = N + ((6 - lngHour) / 24);
   tRis=risSetTime(tRis,"Rising",latitude,longitude,cos_zen[it]);
   delta=convertTime(tRis,lngHour,localOffset);
   if(err){
    delta[0]=0;
    delta[1]=0;
    err=false;
   }
   times[i++]=delta[0];
   times[i++]=delta[1];
   
   tSet = N + ((18 - lngHour) / 24);
   tSet=risSetTime(tSet,"Setting",latitude,longitude,cos_zen[it]);
   delta=convertTime(tSet,lngHour,localOffset);
   if(err){
    delta[0]=0;
    delta[1]=0;
    err=false;
   }    
   times[i++]=delta[0];
   times[i++]=delta[1];
   it++;
  }

  float rtime=(float)times[0]+(float)times[1]/60;
  float daytime=((float)times[2]+(float)times[3]/60)-rtime; 
  float otime=((daytime)/2)+rtime;
  times[i++]=(int)otime;       
  times[i++]=(int)(otime%1*60);
  times[i++]=(int)daytime;    
  times[i]=(int)(daytime%1*60);
  return(times);
 }
 
 private int getDay(int day,int month,int year){
       
  double N,N1,N2,N3;
  
  N1 = Math.floor(275 * month / 9);
  N2 = Math.floor((month + 9) / 12);
  N3 = (1 + Math.floor((year - 4 * Math.floor(year / 4) + 2) / 3));
  N = N1 - (N2 * N3) + day - 30;
  
  return((int)N);
 }

 private float risSetTime(float t,String param,float latitude,float longitude,
                                 float cos_zen){
  
  float M,L,RA,Lquad,RAquad,sinDec,cosDec,cosH,H=0,T;
  float grad=180/(float)Math.PI;
  float rad=(float)Math.PI/180;

  M = (0.9856F * t) - 3.289F;
  
  //[0,360]
  L =M + (1.916F * (float)Math.sin(M*rad)) + 
                             (0.020F * (float)Math.sin(2 * M*rad)) + 282.634F;
  if(L>360) 
   L-=360;
  if(L<0) 
   L+=360;
  
  RA = (float)Math.atan(0.91764D * Math.tan(L*rad))*grad;
  
  //L and RA
  Lquad  = (float)(Math.floor( L/90)) * 90;
  RAquad = (float)(Math.floor(RA/90)) * 90;
  RA = RA + (Lquad - RAquad);
  if((L-RA)>90 || (RA-L)<0)
   err=true; 

  RA = RA / 15;
  
  sinDec = 0.39782F * (float)Math.sin(L*rad);
  cosDec = (float)Math.cos(Math.asin(sinDec));
  
  //cosH = (float)((cos_zen - (sinDec * Math.sin(latitude*rad))) / 
                          (cosDec * Math.cos(latitude*rad)));
  if(cosH>1) 
   err=true; 
  if(cosH<-1) 
   err=true; 
  
  if(param=="Rising") 
   H=360-grad*(float)Math.acos(cosH);
  if(param=="Setting") 
   H=grad*(float)Math.acos(cosH);
  H=H/15;
  
  T = H + RA - (0.06571F * t) - 6.622F;
  
  return(T);
 }

 private int[] convertTime(double T,double lngHour,float localOffset){
 
  double UT;
  int[] massOut=new int[2];

  UT = T - lngHour;
  
  massOut[0]=(int)UT;        
  massOut[1]=(int)(UT%1*60);  
  massOut[0] += (int)localOffset;
  massOut[1] += (int)(localOffset%1*100); 
  
  if(massOut[0]<0) 
   massOut[0]+=24;
  if(massOut[0]>24) 
   massOut[0]-=24;
  if(massOut[0]==0)
   massOut[0]=24;
  if(massOut[1]<0) {
   massOut[1]+=60;
      massOut[0]--;
  }
  if(massOut[1]>60){ 
   massOut[1]-=60;
   massOut[0]++;
  }
  
  return(massOut);
 }
}

Комментарии

Популярные сообщения из этого блога

Пик Ленина (полезные заметки самостоятельного восходителя)

Только осознание своей не вечности дарит путь в стремительном потоке жизни ... Only the realization of your own not eternity

Skoda Kodiaq отзывы