Skip to content
Snippets Groups Projects
Commit d8250250 authored by Stephen Leger's avatar Stephen Leger
Browse files

lamp_geographical_sun T49359 fix mess with east and west

parent e1a1159c
Branches
Tags
No related merge requests found
...@@ -31,13 +31,13 @@ import datetime, math, time ...@@ -31,13 +31,13 @@ import datetime, math, time
today = datetime.datetime.now() today = datetime.datetime.now()
# Blender imports # Blender imports
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
import bpy import bpy
from extensions_framework import Addon, declarative_property_group from extensions_framework import Addon, declarative_property_group
from extensions_framework.ui import property_group_renderer from extensions_framework.ui import property_group_renderer
# Addon setup # Addon setup
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
bl_info = { bl_info = {
"name": "Geographical Sun", "name": "Geographical Sun",
"author": "Doug Hammond (dougal2)", "author": "Doug Hammond (dougal2)",
...@@ -53,7 +53,7 @@ bl_info = { ...@@ -53,7 +53,7 @@ bl_info = {
GeoSunAddon = Addon(bl_info) GeoSunAddon = Addon(bl_info)
# Sun rotation calculator implementation # Sun rotation calculator implementation
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
class sun_calculator(object): class sun_calculator(object):
""" """
Based on SunLight v1.0 by Miguel Kabantsov (miguelkab@gmail.com) Based on SunLight v1.0 by Miguel Kabantsov (miguelkab@gmail.com)
...@@ -61,7 +61,7 @@ class sun_calculator(object): ...@@ -61,7 +61,7 @@ class sun_calculator(object):
Co-Ordinates: http://www.bcca.org/misc/qiblih/latlong.html Co-Ordinates: http://www.bcca.org/misc/qiblih/latlong.html
Author: Nils-Peter Fischer (Nils-Peter.Fischer@web.de) Author: Nils-Peter Fischer (Nils-Peter.Fischer@web.de)
""" """
location_list = [ location_list = [
("EUROPE",[ ("EUROPE",[
("Antwerp, Belgium", 67), ("Antwerp, Belgium", 67),
...@@ -85,7 +85,7 @@ class sun_calculator(object): ...@@ -85,7 +85,7 @@ class sun_calculator(object):
("Wroclaw, Poland", 73), ("Wroclaw, Poland", 73),
("Zurich, Switzerland", 21), ("Zurich, Switzerland", 21),
]), ]),
("WORLD CITIES", [ ("WORLD CITIES", [
("Beijing, China", 0), ("Beijing, China", 0),
("Bombay, India", 2), ("Bombay, India", 2),
...@@ -107,7 +107,7 @@ class sun_calculator(object): ...@@ -107,7 +107,7 @@ class sun_calculator(object):
("Sydney, Australia", 19), ("Sydney, Australia", 19),
("Tokyo, Japan", 20), ("Tokyo, Japan", 20),
]), ]),
("US CITIES", [ ("US CITIES", [
("Albuquerque, NM", 22), ("Albuquerque, NM", 22),
("Anchorage, AK", 23), ("Anchorage, AK", 23),
...@@ -147,111 +147,111 @@ class sun_calculator(object): ...@@ -147,111 +147,111 @@ class sun_calculator(object):
("Washington DC", 57), ("Washington DC", 57),
]) ])
] ]
location_data = { location_data = {
# Europe # Europe
67: ( 51.2167, -4.4, 1), 67: ( 51.2167, 4.4, 1),
1: ( 52.33, -13.30, 1), 1: ( 52.33, 13.30, 1),
70: ( 48.17, -17.17, 1), 70: ( 48.17, 17.17, 1),
72: ( 49.2, -16.63, 1), 72: ( 49.2, 16.63, 1),
68: ( 58.8467, -4.3525, 1), 68: ( 58.8467, 4.3525, 1),
65: ( 46.217, -6.150, 1), 65: ( 46.217, 6.150, 1),
7: ( 60.1667, -24.9667,2), 7: ( 60.1667, 24.9667,2),
62: ( 47.2672, -11.3928, 1), 62: ( 47.2672, 11.3928, 1),
64: ( 50.75, -30.0833, 2), 64: ( 50.75, 30.0833, 2),
10: ( 51.50, 0.0, 0), 10: ( 51.50, 0.0, 0),
66: ( 45.767, -4.833, 1), 66: ( 45.767, 4.833, 1),
69: ( 48.32, -18.07, 1), 69: ( 48.32, 18.07, 1),
58: ( 59.56, -10.41, 1), 58: ( 59.56, 10.41, 1),
15: ( 48.8667, -2.667, 1), 15: ( 48.8667, 2.667, 1),
71: ( 50.08, -14.46, 1), 71: ( 50.08, 14.46, 1),
18: ( 41.90, -12.4833, 1), 18: ( 41.90, 12.4833, 1),
63: ( 47.3, -11.0667, 1), 63: ( 47.3, 11.0667, 1),
74: ( 52.232, -21.008, 1), 74: ( 52.232, 21.008, 1),
73: ( 51.108, -17.038, 1), 73: ( 51.108, 17.038, 1),
21: ( 47.3833, -8.5333, 1), 21: ( 47.3833, 8.5333, 1),
# World Cities # World Cities
0: ( 39.9167, -116.4167, 8), 0: ( 39.9167, 116.4167, 8),
2: ( 18.9333, -72.8333, 5.5), 2: ( 18.9333, 72.8333, 5.5),
3: (-34.60, 58.45, -3), 3: (-34.60, -58.45, -3),
4: ( 30.10, -31.3667, 2), 4: ( 30.10, 31.3667, 2),
5: (-33.9167, -18.3667, 2), 5: (-33.9167, 18.3667, 2),
6: ( 10.50, 66.9333, -4), 6: ( 10.50, -66.9333, -4),
60: (-25.4278, 49.2731, -3), 60: (-25.4278, -49.2731, -3),
8: ( 22.25, -114.1667, 8), 8: ( 22.25, 114.1667, 8),
9: ( 31.7833, -35.2333, 2), 9: ( 31.7833, 35.2333, 2),
61: (-29.3044, 48.8456, -3), 61: (-29.3044, -48.8456, -3),
11: ( 19.4, 99.15, -6), 11: ( 19.4, -99.15, -6),
12: ( 55.75, -37.5833, 3), 12: ( 55.75, 37.5833, 3),
13: ( 28.6, -77.2, 5.5), 13: ( 28.6, 77.2, 5.5),
14: ( 45.41667, 75.7, -5), 14: ( 45.41667, -75.7, -5),
16: (-22.90, 43.2333, -3), 16: (-22.90, -43.2333, -3),
17: ( 24.633, -46.71667, 3), 17: ( 24.633, 46.71667, 3),
59: ( -23.5475, 46.6361, -3), 59: ( -23.5475, -46.6361, -3),
19: (-33.8667, -151.2167,10), 19: (-33.8667, 151.2167,10),
20: ( 35.70, -139.7667, 9), 20: ( 35.70, 139.7667, 9),
# US Cities # US Cities
22: ( 35.0833, 106.65, -7), 22: ( 35.0833, -106.65, -7),
23: ( 61.217, 149.90, -9), 23: ( 61.217, -149.90, -9),
24: ( 33.733, 84.383, -5), 24: ( 33.733, -84.383, -5),
25: ( 30.283, 97.733, -6), 25: ( 30.283, -97.733, -6),
26: ( 33.521, 86.8025, -6), 26: ( 33.521, -86.8025, -6),
27: ( 46.817, 100.783, -6), 27: ( 46.817, -100.783, -6),
28: ( 42.35, 71.05, -5), 28: ( 42.35, -71.05, -5),
29: ( 40.125, 105.237, -7), 29: ( 40.125, -105.237, -7),
30: ( 41.85, 87.65, -6), 30: ( 41.85, -87.65, -6),
31: ( 32.46, 96.47, -6), 31: ( 32.46, -96.47, -6),
32: ( 39.733, 104.983, -7), 32: ( 39.733, -104.983, -7),
33: ( 42.333, 83.05, -5), 33: ( 42.333, -83.05, -5),
34: ( 21.30, 157.85, -10), 34: ( 21.30, -157.85, -10),
35: ( 29.75, 95.35, -6), 35: ( 29.75, -95.35, -6),
36: ( 39.767, 86.15, -5), 36: ( 39.767, -86.15, -5),
37: ( 32.283, 90.183, -6), 37: ( 32.283, -90.183, -6),
38: ( 39.083, 94.567, -6), 38: ( 39.083, -94.567, -6),
39: ( 34.05, 118.233, -8), 39: ( 34.05, -118.233, -8),
40: ( 43.11, 88.10, -6), 40: ( 43.11, -88.10, -6),
41: ( 25.767, 80.183, -5), 41: ( 25.767, -80.183, -5),
42: ( 44.967, 93.25, -6), 42: ( 44.967, -93.25, -6),
43: ( 29.95, 90.067, -6), 43: ( 29.95, -90.067, -6),
44: ( 40.7167, 74.0167, -5), 44: ( 40.7167, -74.0167, -5),
45: ( 35.483, 97.533, -6), 45: ( 35.483, -97.533, -6),
46: ( 39.95, 75.15, -5), 46: ( 39.95, -75.15, -5),
47: ( 33.433, 112.067,-7), 47: ( 33.433, -112.067,-7),
48: ( 40.433, 79.9833, -5), 48: ( 40.433, -79.9833, -5),
49: ( 43.666, 70.283, -5), 49: ( 43.666, -70.283, -5),
50: ( 45.517, 122.65, -8), 50: ( 45.517, -122.65, -8),
51: ( 35.783, 78.65, -5), 51: ( 35.783, -78.65, -5),
52: ( 37.5667, 77.450, -5), 52: ( 37.5667, -77.450, -5),
53: ( 38.6167, 90.1833, -6), 53: ( 38.6167, -90.1833, -6),
54: ( 32.7667, 117.2167, -8), 54: ( 32.7667, -117.2167, -8),
55: ( 37.7667, 122.4167, -8), 55: ( 37.7667, -122.4167, -8),
56: ( 47.60, 122.3167, -8), 56: ( 47.60, -122.3167, -8),
57: ( 38.8833, 77.0333, -5), 57: ( 38.8833, -77.0333, -5),
} }
# mathematical helpers # mathematical helpers
@staticmethod @staticmethod
def sind(deg): def sind(deg):
return math.sin(math.radians(deg)) return math.sin(math.radians(deg))
@staticmethod @staticmethod
def cosd(deg): def cosd(deg):
return math.cos(math.radians(deg)) return math.cos(math.radians(deg))
@staticmethod @staticmethod
def tand(deg): def tand(deg):
return math.tan(math.radians(deg)) return math.tan(math.radians(deg))
@staticmethod @staticmethod
def asind(deg): def asind(deg):
return math.degrees(math.asin(deg)) return math.degrees(math.asin(deg))
@staticmethod @staticmethod
def atand(deg): def atand(deg):
return math.degrees(math.atan(deg)) return math.degrees(math.atan(deg))
@staticmethod @staticmethod
def geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone): def geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone):
if Month > 2.0: if Month > 2.0:
...@@ -260,13 +260,13 @@ class sun_calculator(object): ...@@ -260,13 +260,13 @@ class sun_calculator(object):
else: else:
Y = Year - 1.0 Y = Year - 1.0
M = Month + 12.0 M = Month + 12.0
UT = LocalTime - Timezone UT = LocalTime - Timezone
hour = UT / 24.0 hour = UT / 24.0
A = int(Y/100.0) A = int(Y/100.0)
JD = math.floor(365.25*(Y+4716.0)) + math.floor(30.6001*(M+1.0)) + Day + hour - 1524.4 JD = math.floor(365.25*(Y+4716.0)) + math.floor(30.6001*(M+1.0)) + Day + hour - 1524.4
# The following section is adopted from netCDF4 netcdftime implementation. # The following section is adopted from netCDF4 netcdftime implementation.
# Copyright: 2008 by Jeffrey Whitaker # Copyright: 2008 by Jeffrey Whitaker
# License: http://www.opensource.org/licenses/mit-license.php # License: http://www.opensource.org/licenses/mit-license.php
...@@ -279,71 +279,71 @@ class sun_calculator(object): ...@@ -279,71 +279,71 @@ class sun_calculator(object):
else: else:
raise Exception('ERROR: Date falls in the gap between Julian and Gregorian calendars.') raise Exception('ERROR: Date falls in the gap between Julian and Gregorian calendars.')
B = 0 B = 0
return JD+B return JD+B
@staticmethod @staticmethod
def geoSunData(Latitude, Longitude, Year, Month, Day, LocalTime, Timezone): def geoSunData(Latitude, Longitude, Year, Month, Day, LocalTime, Timezone):
JD = sun_calculator.geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone) JD = sun_calculator.geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone)
phi = Latitude phi = Latitude
llambda = Longitude llambda = Longitude
n = JD - 2451545.0 n = JD - 2451545.0
LDeg = (280.460 + 0.9856474*n) - (math.floor((280.460 + 0.9856474*n)/360.0) * 360.0) LDeg = (280.460 + 0.9856474*n) - (math.floor((280.460 + 0.9856474*n)/360.0) * 360.0)
gDeg = (357.528 + 0.9856003*n) - (math.floor((357.528 + 0.9856003*n)/360.0) * 360.0) gDeg = (357.528 + 0.9856003*n) - (math.floor((357.528 + 0.9856003*n)/360.0) * 360.0)
LambdaDeg = LDeg + 1.915 * sun_calculator.sind(gDeg) + 0.02 * sun_calculator.sind(2.0*gDeg) LambdaDeg = LDeg + 1.915 * sun_calculator.sind(gDeg) + 0.02 * sun_calculator.sind(2.0*gDeg)
epsilonDeg = 23.439 - 0.0000004*n epsilonDeg = 23.439 - 0.0000004*n
alphaDeg = sun_calculator.atand( (sun_calculator.cosd(epsilonDeg) * sun_calculator.sind(LambdaDeg)) / sun_calculator.cosd(LambdaDeg) ) alphaDeg = sun_calculator.atand( (sun_calculator.cosd(epsilonDeg) * sun_calculator.sind(LambdaDeg)) / sun_calculator.cosd(LambdaDeg) )
if sun_calculator.cosd(LambdaDeg) < 0.0: if sun_calculator.cosd(LambdaDeg) < 0.0:
alphaDeg += 180.0 alphaDeg += 180.0
deltaDeg = sun_calculator.asind( sun_calculator.sind(epsilonDeg) * sun_calculator.sind(LambdaDeg) ) deltaDeg = sun_calculator.asind( sun_calculator.sind(epsilonDeg) * sun_calculator.sind(LambdaDeg) )
JDNull = sun_calculator.geo_sun_astronomicJulianDate(Year, Month, Day, 0.0, 0.0) JDNull = sun_calculator.geo_sun_astronomicJulianDate(Year, Month, Day, 0.0, 0.0)
TNull = (JDNull - 2451545.0) / 36525.0 TNull = (JDNull - 2451545.0) / 36525.0
T = LocalTime - Timezone T = LocalTime - Timezone
thetaGh = 6.697376 + 2400.05134*TNull + 1.002738*T thetaGh = 6.697376 + 2400.05134*TNull + 1.002738*T
thetaGh -= math.floor(thetaGh/24.0) * 24.0 thetaGh -= math.floor(thetaGh/24.0) * 24.0
thetaG = thetaGh * 15.0 thetaG = thetaGh * 15.0
theta = thetaG + llambda theta = thetaG + llambda
tau = theta - alphaDeg tau = theta - alphaDeg
a = sun_calculator.atand( sun_calculator.sind(tau) / ( sun_calculator.cosd(tau)*sun_calculator.sind(phi) - sun_calculator.tand(deltaDeg)*sun_calculator.cosd(phi)) ) a = sun_calculator.atand( sun_calculator.sind(tau) / ( sun_calculator.cosd(tau)*sun_calculator.sind(phi) - sun_calculator.tand(deltaDeg)*sun_calculator.cosd(phi)) )
if sun_calculator.cosd(tau)*sun_calculator.sind(phi) - sun_calculator.tand(deltaDeg)*sun_calculator.cosd(phi) < 0.0: if sun_calculator.cosd(tau)*sun_calculator.sind(phi) - sun_calculator.tand(deltaDeg)*sun_calculator.cosd(phi) < 0.0:
a += 180.0 a += 180.0
h = sun_calculator.asind( sun_calculator.cosd(deltaDeg)*sun_calculator.cosd(tau)*sun_calculator.cosd(phi) + sun_calculator.sind(deltaDeg)*sun_calculator.sind(phi) ) h = sun_calculator.asind( sun_calculator.cosd(deltaDeg)*sun_calculator.cosd(tau)*sun_calculator.cosd(phi) + sun_calculator.sind(deltaDeg)*sun_calculator.sind(phi) )
R = 1.02 / (sun_calculator.tand (h+(10.3/(h+5.11)))) R = 1.02 / (sun_calculator.tand (h+(10.3/(h+5.11))))
hR = h + R/60.0 hR = h + R/60.0
azimuth = a azimuth = a
elevation = hR elevation = hR
return azimuth, elevation return -azimuth, elevation
# Addon classes # Addon classes
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
@GeoSunAddon.addon_register_class @GeoSunAddon.addon_register_class
class OBJECT_OT_set_geographical_sun_now(bpy.types.Operator): class OBJECT_OT_set_geographical_sun_now(bpy.types.Operator):
bl_idname = 'object.set_geographical_sun_now' bl_idname = 'object.set_geographical_sun_now'
bl_label = 'Set time to NOW' bl_label = 'Set time to NOW'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
cl = context.lamp cl = context.lamp
return cl and cl.type == 'SUN' return cl and cl.type == 'SUN'
def execute(self, context): def execute(self, context):
GSP = context.lamp.GeoSunProperties GSP = context.lamp.GeoSunProperties
now = datetime.datetime.now() now = datetime.datetime.now()
for p in ("hour", "minute", "day", "month", "year"): for p in ("hour", "minute", "day", "month", "year"):
setattr( setattr(
...@@ -353,25 +353,25 @@ class OBJECT_OT_set_geographical_sun_now(bpy.types.Operator): ...@@ -353,25 +353,25 @@ class OBJECT_OT_set_geographical_sun_now(bpy.types.Operator):
) )
GSP.tz = time.timezone GSP.tz = time.timezone
GSP.dst = False GSP.dst = False
return {'FINISHED'} return {'FINISHED'}
@GeoSunAddon.addon_register_class @GeoSunAddon.addon_register_class
class OBJECT_OT_set_geographical_sun_pos(bpy.types.Operator): class OBJECT_OT_set_geographical_sun_pos(bpy.types.Operator):
bl_idname = 'object.set_geographical_sun_pos' bl_idname = 'object.set_geographical_sun_pos'
bl_label = 'Set SUN position' bl_label = 'Set SUN position'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
cl = context.lamp cl = context.lamp
return cl and cl.type == 'SUN' return cl and cl.type == 'SUN'
def execute(self, context): def execute(self, context):
try: try:
GSP = context.lamp.GeoSunProperties GSP = context.lamp.GeoSunProperties
dst = 1 if GSP.dst else 0 dst = 1 if GSP.dst else 0
az,el = sun_calculator.geoSunData( az,el = sun_calculator.geoSunData(
GSP.lat, GSP.lat,
GSP.long, GSP.long,
...@@ -381,8 +381,8 @@ class OBJECT_OT_set_geographical_sun_pos(bpy.types.Operator): ...@@ -381,8 +381,8 @@ class OBJECT_OT_set_geographical_sun_pos(bpy.types.Operator):
GSP.hour + GSP.minute/60.0, GSP.hour + GSP.minute/60.0,
-GSP.tz + dst -GSP.tz + dst
) )
context.object.rotation_euler = ( math.radians(90-el), 0, math.radians(-az) ) context.object.rotation_euler = ( math.radians(90-el), 0, math.radians(az) )
return {'FINISHED'} return {'FINISHED'}
except Exception as err: except Exception as err:
self.report({'ERROR'}, str(err)) self.report({'ERROR'}, str(err))
...@@ -392,14 +392,14 @@ class OBJECT_OT_set_geographical_sun_pos(bpy.types.Operator): ...@@ -392,14 +392,14 @@ class OBJECT_OT_set_geographical_sun_pos(bpy.types.Operator):
class OBJECT_OT_set_geographical_location_preset(bpy.types.Operator): class OBJECT_OT_set_geographical_location_preset(bpy.types.Operator):
bl_idname = 'object.set_geographical_location_preset' bl_idname = 'object.set_geographical_location_preset'
bl_label = 'Apply location preset' bl_label = 'Apply location preset'
index = bpy.props.IntProperty() index = bpy.props.IntProperty()
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
cl = context.lamp cl = context.lamp
return cl and cl.type == 'SUN' return cl and cl.type == 'SUN'
def execute(self, context): def execute(self, context):
GSP = context.lamp.GeoSunProperties GSP = context.lamp.GeoSunProperties
GSP.lat, GSP.long, GSP.tz = sun_calculator.location_data[self.properties.index] GSP.lat, GSP.long, GSP.tz = sun_calculator.location_data[self.properties.index]
...@@ -433,7 +433,7 @@ for label, locations in sun_calculator.location_list: ...@@ -433,7 +433,7 @@ for label, locations in sun_calculator.location_list:
@GeoSunAddon.addon_register_class @GeoSunAddon.addon_register_class
class OBJECT_MT_geo_sun_location(bpy.types.Menu): class OBJECT_MT_geo_sun_location(bpy.types.Menu):
bl_label = 'Location preset' bl_label = 'Location preset'
def draw(self, context): def draw(self, context):
sl = self.layout sl = self.layout
for sm in submenus: for sm in submenus:
...@@ -442,7 +442,7 @@ class OBJECT_MT_geo_sun_location(bpy.types.Menu): ...@@ -442,7 +442,7 @@ class OBJECT_MT_geo_sun_location(bpy.types.Menu):
@GeoSunAddon.addon_register_class @GeoSunAddon.addon_register_class
class GeoSunProperties(declarative_property_group): class GeoSunProperties(declarative_property_group):
ef_attach_to = ['Lamp'] ef_attach_to = ['Lamp']
controls = [ controls = [
['hour', 'minute'], ['hour', 'minute'],
['day', 'month', 'year'], ['day', 'month', 'year'],
...@@ -451,7 +451,7 @@ class GeoSunProperties(declarative_property_group): ...@@ -451,7 +451,7 @@ class GeoSunProperties(declarative_property_group):
['lat', 'long'], ['lat', 'long'],
['set_time', 'set_posn'], ['set_time', 'set_posn'],
] ]
properties = [ properties = [
{ {
'type': 'int', 'type': 'int',
...@@ -539,7 +539,7 @@ class GeoSunProperties(declarative_property_group): ...@@ -539,7 +539,7 @@ class GeoSunProperties(declarative_property_group):
'soft_max': 90.0, 'soft_max': 90.0,
'default': 0.0 'default': 0.0
}, },
# draw operators and menus # draw operators and menus
{ {
'attr': 'location_menu', 'attr': 'location_menu',
...@@ -566,16 +566,16 @@ class GeoSunPanel(property_group_renderer): ...@@ -566,16 +566,16 @@ class GeoSunPanel(property_group_renderer):
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_context = 'data' bl_context = 'data'
bl_label = 'Geographical Sun' bl_label = 'Geographical Sun'
display_property_groups = [ display_property_groups = [
( ('lamp',), 'GeoSunProperties' ) ( ('lamp',), 'GeoSunProperties' )
] ]
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
cl = context.lamp cl = context.lamp
return cl and cl.type == 'SUN' return cl and cl.type == 'SUN'
# Bootstrap the Addon # Bootstrap the Addon
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
register, unregister = GeoSunAddon.init_functions() register, unregister = GeoSunAddon.init_functions()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment