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