Last active
August 23, 2017 20:09
-
-
Save leebyron/5678b01db7b28322f937 to your computer and use it in GitHub Desktop.
Solar relative position math from Solar Calendar.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Gradient2D{ | |
PImage source; | |
Gradient2D(String src){ | |
source = loadImage(src); | |
} | |
color get(float g1, float g2){ | |
int x = constrain( floor( g1*source.width ), 0, source.width-1); | |
int y = constrain( floor( g2*source.height ), 0, source.height-1); | |
int p = x + y*source.width; | |
return source.pixels[p]; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Does some crazy math and figures out all kinds of things about the sun | |
* Lee Byron - Dec 2006 | |
*/ | |
public class Sun{ | |
final double K = PI/180; | |
double latitude, longitude; | |
Calendar calendar; | |
double hour; | |
double eqtime, time_offset, tst, ha; | |
double declin, Phi, Phi1, Theta, hars; | |
double sun_rise, sun_set, snoon; | |
Sun(double latitude, double longitude, Calendar calendar){ | |
this.latitude = latitude; | |
this.longitude = longitude; | |
this.calendar = calendar; | |
} | |
void calculate(double hour){ | |
this.hour = hour; | |
equationTime(); | |
declination(); | |
tzo(); | |
solarTime(); | |
hourAngle(); | |
zenithAngle(); | |
azimuthAngle(); | |
hourAngleRiseSet(); | |
RiseSet(); | |
noon(); | |
} | |
double getZenith(){ | |
return Phi1; | |
} | |
// equation of time (in minutes) | |
private void equationTime(){ | |
double x = calendar.get(Calendar.DAY_OF_YEAR)*TWO_PI/365; | |
eqtime = 229.18*(0.000075+0.001868*Math.cos(x)-0.032077*Math.sin(x)-0.014615*Math.cos(2*x)-0.040849*Math.sin(2*x)); | |
} | |
// declination (in degrees) | |
private void declination(){ | |
double x = calendar.get(Calendar.DAY_OF_YEAR)*TWO_PI/365; // fractional year in radians | |
declin = ( 0.006918 - 0.399912*Math.cos(x) + 0.070257*Math.sin(x) - 0.006758*Math.cos(2*x) + 0.000907*Math.sin(2*x) - 0.002697*Math.cos(3*x) + 0.00148*Math.sin(3*x) )*180/Math.PI; | |
} | |
// time offset (in minutes) | |
private void tzo(){ | |
// we're using timezone offset minutes here | |
double offsetMinutes = (calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET))/60000; | |
time_offset = eqtime - 4*longitude + offsetMinutes; | |
} | |
// true solar time (in hours) // looks like minutes to me? | |
private void solarTime() { | |
tst = hour*60 - time_offset; | |
} | |
// solar hour angle (in degrees) | |
private void hourAngle() { | |
ha = tst/4 - 180; | |
} | |
// solar zenith angle (in degrees) | |
private void zenithAngle() { | |
Phi = Math.sin(K*latitude)*Math.sin(K*declin)+Math.cos(K*latitude)*Math.cos(K*declin)*Math.cos(K*ha); | |
Phi = Math.acos(Phi)/K; | |
Phi1 = 90-Phi; // altitude | |
} | |
// solar azimuth angle (in degrees, clockwise from north) | |
private void azimuthAngle() { | |
Theta = -(Math.sin(K*latitude)*Math.cos(K*Phi)-Math.sin(K*declin))/(Math.cos(K*latitude)*Math.sin(K*Phi)); | |
Theta = Math.acos(Theta)/K; | |
if (ha<0) Theta=Theta; | |
else Theta=360-Theta; | |
} | |
// solar azimuth angle for sunrise and sunset corrected for atmospheric refraction (in degrees), | |
private void hourAngleRiseSet() { | |
hars = Math.cos(K*90.833)/(Math.cos(K*latitude)*Math.cos(K*declin)) - Math.tan(K*latitude)*Math.tan(K*declin); | |
hars = Math.acos(hars)/K; | |
} | |
// sunrise and sunset (local time) | |
private void RiseSet() { | |
// we're using timezone offset hours here | |
double offsetHours = (calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET))/3600000; | |
sun_rise = 720 + 4*(longitude-hars) - eqtime; | |
sun_rise = sun_rise/60 - offsetHours; | |
sun_set = 720 + 4*(longitude+hars) - eqtime; | |
sun_set = sun_set/60 - offsetHours; | |
} | |
// solar noon (local time) | |
private void noon() { | |
// we're using timezone offset hours here | |
double offsetHours = (calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET))/3600000; | |
snoon = 720 + 4*longitude - eqtime; | |
snoon = snoon/60 - offsetHours; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
With this code I'm unable to properly get the Sun_rise/Sun_Set using your RiseSet() function. Based on calculations here you seem to be mixing up the +'s and -'s during the calculations
I use the following and I'm able to get within 1.5 minutes of the sun rise/set: