1 registered members (TipmyPip),
18,449
guests, and 6
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
real sun position by time, date and location
#421985
04/29/13 22:02
04/29/13 22:02
|
Joined: Aug 2002
Posts: 3,258 Mainz
oliver2s
OP
Expert
|
OP
Expert
Joined: Aug 2002
Posts: 3,258
Mainz
|
The following function sets the real sun position by setting time of day, day of year and current location (latitude) paramters:
#define DEGREE_IN_RADIANS 0.0174532925
#define EARTH_AXIAL_TILT 23.5 //earth axial tilt in degrees
#define EARTH_ORBITAL_PERIOD 365.25 //earth orbital period in days (length of a year)
#define EARTH_ROTATION_PERIOD 24.0 //earth rotation period in hours (length of a day)
#define LOCATION_TIME_SPRING_EQUINOX 81.0 //day number of the year when day and night cycle is exactly 12/12 hours
#define LOCATION_LATITUDE 48.0 //latitude of current location
void set_sun_position(var day_,var hour_,var minute_,var second_,var latitude_,var spring_equinox_)
{
double B=(360.0/EARTH_ORBITAL_PERIOD) * (day_-spring_equinox_);
//Equation of Time (EoT)
double EoT=9.87*sin(2*B*DEGREE_IN_RADIANS) - 7.53*cos(B*DEGREE_IN_RADIANS) - 1.5*sin(B*DEGREE_IN_RADIANS);
//Time Correction Factor (TC)
double TC=EoT;
//Local Time (LT)
double LT=hour_ + (minute_/60.0) + (second_/3600.0);
//Local Solar Time (LST)
double LST=LT + TC/60.0;
//Hour Angle (HRA)
double HRA=15.0 * (LST - 12.0);
//Number of days since the start of the year (d)
double d=day_ + LT/24.0;
//Declination (D)
double D=EARTH_AXIAL_TILT * sin((360.0/EARTH_ORBITAL_PERIOD) * (d - spring_equinox_) * DEGREE_IN_RADIANS);
//Sun Elevation (sun_angle.tilt)
double sun_angle_tilt_sin=cos(HRA*DEGREE_IN_RADIANS)*cos(D*DEGREE_IN_RADIANS)*cos(LOCATION_LATITUDE*DEGREE_IN_RADIANS)+sin(D*DEGREE_IN_RADIANS)*sin(LOCATION_LATITUDE*DEGREE_IN_RADIANS);
if(sun_angle_tilt_sin < -1){sun_angle_tilt_sin=-1;}
if(sun_angle_tilt_sin > 1){sun_angle_tilt_sin=1;}
double sun_angle_tilt=asin(sun_angle_tilt_sin)/DEGREE_IN_RADIANS;
//Sun Azimuth (sun_angle.pan)
double sun_angle_pan_cos=(sin(D*DEGREE_IN_RADIANS)-sin(sun_angle_tilt*DEGREE_IN_RADIANS)*sin(LOCATION_LATITUDE*DEGREE_IN_RADIANS))/(cos(sun_angle_tilt*DEGREE_IN_RADIANS)*cos(LOCATION_LATITUDE*DEGREE_IN_RADIANS));
if(sun_angle_pan_cos < -1){sun_angle_pan_cos=-1;}
if(sun_angle_pan_cos > 1){sun_angle_pan_cos=1;}
double sun_angle_pan=acos(sun_angle_pan_cos)/DEGREE_IN_RADIANS;
if(LST>12.0 && HRA>0.0){sun_angle_pan=360.0-sun_angle_pan;}
sun_angle_pan=cycle(sun_angle_pan,0,360);
sun_angle.pan=sun_angle_pan;
sun_angle.tilt=sun_angle_tilt;
}
Here's an example how to call the function:
//set sun position to day 181 (june 30th) at time 14:30:00 (2:30 P.M.)
set_sun_position(181,14,30,0,LOCATION_LATITUDE,LOCATION_TIME_SPRING_EQUINOX);
The formulas of this function are taken from this websites: http://pvcdrom.pveducation.org/SUNLIGHT/SUNPOS.HTMhttp://pveducation.org/pvcdrom/properties-of-sunlight/sun-position-calculatorhttp://pveducation.org/pvcdrom/properties-of-sunlight/azimuth-anglehttp://en.wikipedia.org/wiki/Solar_elevation_anglehttp://en.wikipedia.org/wiki/Solar_azimuth_angle
Last edited by oliver2s; 12/24/13 21:14.
|
|
|
Re: real sun position by time, date and location
[Re: Hummel]
#421989
04/30/13 06:14
04/30/13 06:14
|
Joined: Mar 2006
Posts: 1,993 Karlsruhe
PadMalcom
Serious User
|
Serious User
Joined: Mar 2006
Posts: 1,993
Karlsruhe
|
Great, thank you! Would it be okay if I add the function to our TUST library? Here is another small demo:
var day= 0;
var hour = 0;
var minute = 0;
while(1) {
minute++;
if (minute == 60) {
minute = 0;
hour++;
if (hour == 25) {
hour = 0;
day++;
if (day == 366) {
day = 0;
}
}
}
set_sun_position(day,hour,minute,0,LOCATION_LATITUDE,LOCATION_TIME_SPRING_EQUINOX);
wait(1);
}
Last edited by PadMalcom; 04/30/13 06:31.
|
|
|
Re: real sun position by time, date and location
[Re: PadMalcom]
#422005
04/30/13 08:33
04/30/13 08:33
|
Joined: Aug 2002
Posts: 3,258 Mainz
oliver2s
OP
Expert
|
OP
Expert
Joined: Aug 2002
Posts: 3,258
Mainz
|
Great, thank you! Would it be okay if I add the function to our TUST library? Sure, please add it to the TUST library. Here's another script for day/night cycle:
var second_=0;
var minute_=0;
var hour_=12;
var time_speed_=0.5;
var day_=120; //april 30th
while(1)
{
second_+=time_speed_*time_step;
if(second_>=60)
{
minute_+=integer(second_/60);
second_=fraction(second_/60);
if(minute_>=60)
{
hour_+=integer(minute_/60);
minute_=fraction(minute_/60);
hour_%=24;
}
}
set_sun_position(day_,hour_,minute_,second_,LOCATION_LATITUDE,LOCATION_TIME_SPRING_EQUINOX);
wait(1);
}
Last edited by oliver2s; 04/30/13 10:39.
|
|
|
Re: real sun position by time, date and location
[Re: oliver2s]
#422008
04/30/13 10:22
04/30/13 10:22
|
Joined: May 2009
Posts: 5,377 Caucasus
3run
Senior Expert
|
Senior Expert
Joined: May 2009
Posts: 5,377
Caucasus
|
oliver2s@ your last example is not working, minute_ always stays at zero, same for hour.
hour_+=integer(minute_/60);
Doesn't do the trick.. I changed your example like this:
while(1){
DEBUG_VAR(second_, 10);
DEBUG_VAR(minute_, 50);
DEBUG_VAR(hour_, 100);
second_ += time_speed_*time_step;
if(second_ >= 60)
{
second_ = fraction(second_ / 60);
minute_ += 1;
if(minute_ >= 60)
{
minute_ = fraction(minute_ / 60);
hour_+= 1;
hour_ %= 24;
}
}
set_sun_position(day_, hour_, minute_, second_, LOCATION_LATITUDE, LOCATION_TIME_SPRING_EQUINOX);
wait(1);
}
It looks like it works now. Thank you for your contribution anyway. Edit: maybe thats cause I've changed your script wrong, I don't know, but the sun position jerks when the time goes from 11 a.m to 1 p.m. Here is a small example, just take a look at it:
#define EARTH_AXIAL_TILT 23.5 //earth axial tilt in degrees
#define EARTH_ORBITAL_PERIOD 365.25 //earth orbital period in days (length of a year)
#define EARTH_ROTATION_PERIOD 24.0 //earth rotation period in hours (length of a day)
#define LOCATION_TIME_SPRING_EQUINOX 81 //day number of the year when day and night cycle is exactly 12/12 hours
#define LOCATION_LATITUDE 48 //latitude of current location
void set_sun_position(var day_,var hour_,var minute_,var second_,var latitude_,var spring_equinox_)
{
var B=(360/EARTH_ORBITAL_PERIOD) * (day_-spring_equinox_);
//Equation of Time (EoT)
var EoT=9.87*sinv(2*B) - 7.53*cosv(B) - 1.5*sinv(B);
//Time Correction Factor (TC)
var TC=EoT;
//Local Time (LT)
var LT=hour_ + (minute_/60.0) + (second_/3600.0);
//Local Solar Time (LST)
var LST=LT + TC/60;
//Hour Angle (HRA)
var HRA=15 * (LST - 12);
//Number of days since the start of the year (d)
var d=day_ + LT/24;
//Declination (D)
var D=EARTH_AXIAL_TILT * sinv((360/EARTH_ORBITAL_PERIOD) * (d - spring_equinox_));
//Sun Elevation (sun_angle.tilt)
sun_angle.tilt=asinv((cosv(HRA) * cosv(D) * cosv(latitude_)) + (sinv(D) * sinv(latitude_)));
//Sun Azimuth (sun_angle.pan)
sun_angle.pan=acosv( (sinv(D) - sinv(sun_angle.tilt) * sinv(latitude_)) / (cosv(sun_angle.tilt) * cosv(latitude_)) );
if(LST>12 && HRA >0){sun_angle.pan=360-sun_angle.pan;}
}
void main(){
shadow_stencil = 2;
level_load("");
ENTITY* ground = ent_create(CUBE_MDL, vector(0, 0, 0), NULL);
vec_set(ground.scale_x, vector(100, 100, 1));
ENTITY* ball = ent_create(SPHERE_MDL, vector(random(20), random(20), 150), NULL);
set(ball, SHADOW);
vec_set(camera.x, vector(-1436, 0, 897));
vec_set(camera.pan, vector(0, -36, 0));
var second_ = 0;
var minute_ = 0;
var hour_ = 10;
var time_speed_ = 150;
var day_ = 120; // april 30th
while(1)
{
DEBUG_VAR(second_, 10);
DEBUG_VAR(minute_, 50);
DEBUG_VAR(hour_, 100);
second_ += time_speed_*time_step;
if(second_ >= 60)
{
second_ = fraction(second_ / 60);
minute_ += 1;
if(minute_ >= 60)
{
minute_ = fraction(minute_ / 60);
hour_+= 1;
hour_ %= 24;
}
}
set_sun_position(day_, hour_, minute_, second_, LOCATION_LATITUDE, LOCATION_TIME_SPRING_EQUINOX);
wait(1);
}
}
Last edited by 3run; 04/30/13 10:28. Reason: problems..
|
|
|
Re: real sun position by time, date and location
[Re: 3run]
#422009
04/30/13 10:41
04/30/13 10:41
|
Joined: Aug 2002
Posts: 3,258 Mainz
oliver2s
OP
Expert
|
OP
Expert
Joined: Aug 2002
Posts: 3,258
Mainz
|
I switched two lines in the day/night script. I've edited my post above, now it's working. Use my new edited script for increasing time, because if you just increase minutes and hours by 1 (++) like in your script, you don't have a accurate time increasing with high time speed.
I can confirm the problem with the jerking between 11 A.M. and 1 P.M.. I guess the problem is causing by precision of "var" type, maybe "double" does the job. I'll look into this and fix it.
Last edited by oliver2s; 04/30/13 10:47.
|
|
|
|