Extensions:2.4/Py/Scripts/Temp/Sun py

提供: wiki
< Extensions:2.4‎ | Py‎ | Scripts‎ | Temp
移動先: 案内検索

These two bits of code will allow for an animated sun that can be set to a certain time and date for realistic estimations for shadow/light studies. Both scripts are not necessary, but it is recommended that the GUI is used since it will save default values for use with specific blend files. If not, then the current values used will not be saved or if modified will be the same values for all blend files that use it.

you will need to copy and paste each script into a text editor and save into the blender script directory with the name exactly as it is written as the title of each script. After one updates menus in the script window you will find the script and the GUI under Animation with the names: "sun__py" and "sun__py GUI".

sun_gui-D.py

#!BPY
"""
Name: 'sun__py GUI'
Blender: 242
Group: 'Animation'
Tooltip: 'calculated sun path for specific locales and times'
"""
# --------------------------------------------------------------------------
# sun__py GUI
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# Copyright (C) 2006 Patrick7
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
__author__ = "Patrick7"
__url__ = ("blender", "elysiun")
__version__ = "D"
__bpydoc__ = """
Description: GUI for the script that calculates the sun position based on user input data.
Usage: follow the onscreen GUI instuctions as far as setup of objects and your scene or see corresponding usage instructions below.
"""
####################################################
# sun__py
#
# BACKGROUND
####################################################
'''
20060829
Most of the actual script that runs this comes from
a script found here:
	http://blenderartists.org/forum/showthread.php?s=604b30a11e14814c3ec800527ddaa699&t=59884&highlight=sun.py
that orginal script had the following header:
###################################################
#                                                 #
#            Calculating Sun position             #
#            by Grzegorz Rakoczy '2004            #
#                grzybu@obywatel.pl               #
#                                                 #
###################################################
#                                                 #
#       all calculation are based on page         #
#  http://www.stjarnhimlen.se/comp/tutorial.html  #
#                by Paul Schlyter                 #
#                                                 #
################################################### 

called aptly "sun.py".. I was working on a script 
like this when I found there was already one available
I checked the data it out put and compared it to  a 
couple of sources and found this script to actually
be rather accurate (eg wihin about 1% of NOAA
http://www.srrb.noaa.gov/

so I (patrick7) have simply addded a GUI and 
system for saving data while cleaning up some minor
bugs and orientation issues as I saw them.
'''

####################################################
# CODE HISTORY
####################################################
'''
version - date - descriptions
sun_gui-pa1a/b - 060828 - misc building off off original
test-fileioandarrays-pa1 - 060828 - new start
	pa2 - 060828 - ??
	pa3 - 060828 - somewhat functional
	pa4 - 060828 - gibberish trying different things
	pa5 - 060828 - read and gui set works!!
	pa6 - 060828 - working through final details & clean up
sun_gui-pc1 -060829- first functional gui with script
sun_gui-C - 060829 - almost release
sun_gui-0C - 060830 - fixed globals 
sun_gui-D -060903 - fixed crash problem and added web link

## REFERENCE DEFINITIONS
0	long
1	lat
2	year
3	month
4	day
5	hour
6	minute
7	orientation
8	multiplier
9 empty name
'''
####################################################
# OPEN ISSUES
####################################################
'''
0. allow for setting multiple days after a period so
that the highest lowest and middle light periods could
be studied easily
2. allow for multiple objects which requires
	2a. a file per object .. filename needs to be a 
	function to allow for the data to be read correctly
3. script creates a new datablock instance of the script
for each object (>1 or if already loaded) at the time the 
script is run 
'''
####################################################
# USAGE
####################################################
'''
000. Place the gui & script (sun_gui.py and sun.py)
	into your scripts directory
00. Open the GUI script in your script window or open it 
in your text window and hit ALT + P
----------------------------------------------------
0. Scene is oriented by top view [num7], North is
	up (+y), East is right (+x), if this default is
	changed, then those used may not be the same.
	NOTE: IF THE DEFAULT VALUES ARE CHANGED THIS 
	APPLICATION SAVES A FILE (*.dat) IN THE DIRECTORY 
	YOU ARE WORKING
1.In Top view, create a new Empty at the desired
  sun rotation pivot position	
2.Along X-axis of Empty create lamp for Sun,
  position it so far out as needed
3.Select the sun then Empty and parent [ctrl-P],	
4.Change location, time, etc definitions as needed	
5. {Run} runs the script, linking it to the empty if
			script links are enabled.
	{reset} resets default position, clears link
	{rall} as reset plus it deletes the file
	{exit}/[Qkey]/[ESCKEY] quits gui application
'''
####################################################
# THE INCLUDES
####################################################
import Blender, webbrowser
from Blender.BGL import *
from Blender.Draw import *
from Blender import *
import math
from math import *
import os
import array


####################################################
# THE INITIALIZATION OF THE Graphical User Interface
####################################################
DFLTdata= {
	0: 89.600,	#long
	1: 27.483 ,	#lat
	2: 2006,		#yea
	3: 1,				#month
	4: 1,				#day
	5: 0,				#hour
	6: 0.00,		#minute
	7: 0.00,		#orientation
	8: 20.00,		#multiplier
	9: 'Empty'	#empty name
}

n=len(DFLTdata)-1

## Set button variables (settings in the gui)
GUIdata = {
	0:Draw.Create(DFLTdata[0]),
	1:Draw.Create(DFLTdata[1]),
	2:Draw.Create(DFLTdata[2]),
	3:Draw.Create(DFLTdata[3]),
	4:Draw.Create(DFLTdata[4]),
	5:Draw.Create(DFLTdata[5]),
	6:Draw.Create(DFLTdata[6]),
	7:Draw.Create(DFLTdata[7]),
	8:Draw.Create(DFLTdata[8]),
	9:Draw.Create(DFLTdata[9])
}

scriptname = "sun__py"
actualScriptName = "sun-D.py"
FILE = None
fileblend = Blender.Get("filename")
filename = fileblend[:fileblend.rfind(".")] + "_blend-" + scriptname + "-control_data-DO_NOT_DELETE"+".dat"
FILEdata = {}
txt =1 #number of text items
website = ""
	

def opensite(website):
	webbrowser.open(website)


####################################################
# FILE I/O
####################################################
## FILEOPEN
def fileopen():
	global scriptname, filename
	#print scriptname,":FILEOPEN"
	
	try:
		FILE = open(filename, "r")
		print scriptname,":previous data found"
		read(FILE)
	except IOError:
		print scriptname,"no previous data found:",filename
	
	
## READ	- functions, first item is a text item.
def read(FILE):
	global scriptname, GUIdata, FILEdata, n, txt
	i=0	
	#FILE=open(filename,"r")
	while i<=n:
			x = FILE.readline()
			if i<=n-txt: 
					FILEdata[i] = float(x)
			else: 
				x.strip('\n')
				#FILEdata[i]=str(x)
				FILEdata[i]=eval(x)
			GUIdata[i].val = FILEdata[i]
			i=i+1
			startup=1
	FILE.close()
	print scriptname,":DATA READ"
	
	
## WRITE
def write(warray):
	global scriptname, filename, n
	try:
		FILE = open(filename,"w")
	except IOError:
		print scriptname,":IOERROR"
	i=0
	while i<=n:
		FILE.write(str(warray[i])+'\n')
		i=i+1	
	FILE.close()
	print scriptname,":WROTE DATA TO:",filename
	
	
####################################################
# THE RESET
####################################################
def reset():
	global filename, GUIdata
	empty = Blender.Object.Get(GUIdata[9].val)
	empty.clearScriptLinks()
	empty.RotZ = 0
	empty.RotY = 0
	FILE = open(filename, "r")
	FILE.close()
	#Exit()
	
	
def resetevenvalues():
	global scriptname, filename, GUIdata
	empty = Blender.Object.Get(GUIdata[9].val)
	empty.clearScriptLinks()
	empty.RotZ = 0
	empty.RotY = 0
	try:
		FILE = open(filename, "r")
		FILE.close()
		os.remove(filename)
	except os.error:
		print scriptname,":FILE NOT DELETED"
	#Exit()
	
	
####################################################
# script_apply
####################################################
# script shamelessly clipped from Mariano Hidalgo's :
# http://uselessdreamer.byethost32.com/scripts/object_jitter.py
# then HACKED!

def script_apply(ascriptName,objct):
	#global actualScriptName
	
	try:
		print scriptname, "trying to Text.unlink"
		Blender.Text.unlink("sun-D.py")
		print scriptname, "try succeded"
	except:	
		pass	
	try:
		Blender.Text.Load(Blender.Get("scriptsdir") + os.sep + ascriptName)
	except:	
		Blender.Text.Load(Blender.Get("uscriptsdir") + os.sep + ascriptName)
	
	ob = Blender.Object.Get(objct) #$Object.GetSelected()
	try:
		ob.clearScriptLinks()

	except:
		print scriptname, ":Nothing to remove"
	ob.addScriptLink(ascriptName, 'FrameChanged')


####################################################
# RUN
####################################################
def runit ():
	global scriptname, GUIdata
	
	print scriptname,":RUN"
	write(GUIdata)
	script_apply(actualScriptName, GUIdata[9].val)
	
		
####################################################
# THE START SEQUENCE
####################################################
print filename
fileopen()


####################################################
# THE Graphical User Interface
####################################################
def gui():
	global Button11, Button12, Button13, Button14, GUIdata
	
	glClearColor(0.753, 0.753, 0.753, 0.0)
	glClear(GL_COLOR_BUFFER_BIT)
	glColor3f(0.533, 0.533, 0.533)
	glRecti(0, 1, 230, 475)
	glColor3f(0.400, 0.400, 0.400)
	glRecti(88, 116, 227, 180) #note rectangle
	glRecti(145, 85, 175, 125)
	glRecti(0, 47, 229, 0)
	glColor3f(0.000, 0.000, 0.000)
	glRecti(0, 102, 229, 100) #blender fixes
	glRecti(0, 195, 229, 193) #time definition
	glRecti(0, 255, 229, 253) #location definition
	glRecti(0, 445, 229, 443)
	glColor3f(0.000, 0.000, 1.000)
	glRecti(0, 461, 229, 459)
	#glRecti(25, 405, 224, 405)	

	glColor3f(0.000, 0.000, 1.000)
	glRasterPos2i(2, 465)
	Draw.Text('Sun.py v:D (c) 20060903','large')
	glColor3f(0.000, 0.000, 0.000)
	glRasterPos2i(100, 165)
	Draw.Text('NOTE:    changing these','small')
	glRasterPos2i(102, 155)
	Draw.Text('values from zero (0) may','small')
	glRasterPos2i(102, 145)
	Draw.Text('effect the Orientation','small')
	glRasterPos2i(2, 104)
	Draw.Text('Blender Fixes')
	glRasterPos2i(2, 198)
	Draw.Text('Time Definition')
	glColor3f(0.251, 0.000, 0.251)
	glRasterPos2i(2, 446)
	Draw.Text('USAGE:')
	glRasterPos2i(2, 435)
	Draw.Text('0.Scene is oriented by top view [num7], North is','small')
	glRasterPos2i(2, 425)	
	Draw.Text('	up (+y), East is right (+x), if this default is','small')
	glRasterPos2i(2, 415)
	Draw.Text('	changed, then those used may not be the same','small')
	glRasterPos2i(2, 405)	
	Draw.Text('	NOTE: IF THE DEFAULT VALUES ARE ','small')
	glRasterPos2i(2, 395)
	Draw.Text('	CHANGED THIS APP SAVES A FILE (*.dat)','small')
	glRasterPos2i(2, 385)
	Draw.Text('	 IN THE WORKING DIRECTORY','small')	
	glRasterPos2i(2, 375)
	Draw.Text('1.In Top view, create a new Empty at the desired','small')
	glRasterPos2i(2, 365)
	Draw.Text('  sun rotation pivot position	','small')	
	glRasterPos2i(2, 355)
	Draw.Text('2.Along X-axis of Empty create lamp for Sun,','small')	
	glRasterPos2i(2, 345)
	Draw.Text('  position it so far out as needed','small')	
	glRasterPos2i(2, 335)
	Draw.Text('3.Select the sun then Empty and parent [ctrl-P]','small')	
	glRasterPos2i(2, 325)
	Draw.Text('4.Change location, time, etc definitions as needed','small')	
	glRasterPos2i(2, 315)
	Draw.Text('{Run} runs the script, linking it to the empty if','small')	
	glRasterPos2i(2, 305)
	Draw.Text('		script links are enabled.','small')	
	glRasterPos2i(2, 295)
	Draw.Text('  {reset} resets default position, clears link','small')			
	glRasterPos2i(2, 285)
	Draw.Text('  {rall} as reset plus it deletes the file','small')
	glRasterPos2i(2, 275)
	Draw.Text('	{exit}/[Qkey]/[ESCKEY] quits gui application','small')

			
			
	glRasterPos2i(0, 258)
	Draw.Text('Location Definition')

	Button('run',11,5,3,164,34, '')
	Button('reset',12,170,24,29,19,'reset positions and settings')
	Button('rstall',14,200,24,24,19,'reset positions settings AND DELETE default value file')
	Button('exit',13,170,3,54,19,'vamanos')

	Button('www',15,5,210,34,19,'www look up latitude and longitude: http://www.heavens-above.com/countries.asp')

	GUIdata[0] = Draw.Number('Longitude:', 0, 100, 206, 109, 19, GUIdata[0].val, -180, 180, 'Longitude [+180 to -180] (East is positive, zero(0) at the Greenwich Meridian')
	GUIdata[1] = Draw.Number('Latitude:', 1, 5, 231, 99, 19, GUIdata[1].val, -90, 90, 'Latitude [+90 to -90] (North is positive, Equator is zero(0)')
	GUIdata[2] = Number('Year:', 2, 5, 171, 79, 19, GUIdata[2].val, 1901, 2099, 'year [1901-2099]')		
	GUIdata[3] = Number('Month:', 3, 5, 146, 79, 19, GUIdata[3].val, 1, 12, 'month [1-12]')
	GUIdata[4] = Number('Day:', 4, 5, 121, 79, 19, GUIdata[4].val, 1, 31, 'day [1-31]')
	GUIdata[5] = Number('Hr:', 5, 92, 121, 64, 19, GUIdata[5].val, -23, 23, 'hour [0-23]')
	GUIdata[6] = Number('Mn:', 6, 159, 121, 64, 19, GUIdata[6].val, 0, 59, 'minute [0-59]')
	GUIdata[7] = Number('Orientation:', 7, 109, 78, 119, 19, GUIdata[7].val, -360, 360, 'orientation [-360 to 360] positive clockwise (topview [num7] N=+y East=+x at 0° orientation')
	GUIdata[8] = Number('Mn/Frame:', 8, 5, 78, 101, 19, GUIdata[8].val, 0, 1000, 'real life minutes per frame of animation (real time at 24fps is 0.000694) set to 0 for no movement')

	GUIdata[9] = String('', 9, 5, 52, 109, 19, GUIdata[9].val, 399, 'name of the empty (case sensitive)')


####################################################
# CHECK FOR THE ESCAPE KEY or Q (quit)
####################################################
def event(evt, val):
	if (evt== QKEY and not val): 
		print scriptname,":Exit"
		Exit()
	elif (evt==ESCKEY and not val): 
		print scriptname,":Exit"
		Exit()
	
####################################################
# ACTION AFTER THE BUTTON HAS BEEN PRESSED
####################################################	
def bevent(evt):
	if evt == 11: #run
		runit()
	elif evt == 12: #reset
		reset()
	elif evt == 13: #exit
		print scriptname,":Exit"
		Exit()
	elif evt == 14: #reset even values
		resetevenvalues()		
	elif evt == 15: #reset even values
		opensite('http://www.heavens-above.com/countries.asp')

	Blender.Redraw()

Register(gui, event, bevent)

sun-D.py

#!BPY
"""
Name: 'sun__py'
Blender: 242
Group: 'Animation'
Tooltip: 'calculated sun path for specific locales and times'
"""
# --------------------------------------------------------------------------
# sun__py
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# Copyright (C) 2006 Patrick7
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
__author__ = "Grzegorz Rakoczy & Patrick7"
__url__ = ("blender", "elysiun")
__version__ = "D"
__bpydoc__ = """
Description: calculates the sun position based on user input data from the script GUI.
Usage: run via the GUI following the instructions as written there -or- change the default values specifically in this script and run it alt-p. 
"""
####################################################
# sun__py
#
# BACKGROUND
####################################################
'''
20060829
Most of the actual script that runs this comes from
a script originally found here:
	http://blenderartists.org/forum/showthread.php?s=604b30a11e14814c3ec800527ddaa699&t=59884&highlight=sun.py
that orginal script had the following header:
###################################################
#                                                 #
#            Calculating Sun position             #
#            by Grzegorz Rakoczy '2004            #
#                grzybu@obywatel.pl               #
#                                                 #
###################################################
#                                                 #
#       all calculation are based on page         #
#  http://www.stjarnhimlen.se/comp/tutorial.html  #
#                by Paul Schlyter                 #
#                                                 #
################################################### 

called aptly "sun.py".. I was working on a script 
like this when I found there was already one available
I checked the data it out put and compared it to  a 
couple of sources and found this script to actually
be rather accurate (eg wihin about 1% of NOAA calcs
http://www.srrb.noaa.gov/

so I (patrick7) have simply addded a GUI and 
system for saving data while cleaning up some minor
bugs and orientation issues as I saw them.
'''

####################################################
# CODE HISTORY
####################################################
'''
version - date - who - descriptions
Version ?? - Grzegorz Rakoczy '2004 - first release
pb1 - 060825 - patrick7 -Bugs fixed and features added:
		1. orientation, changed to radians for calculation
		2. orientation, automatic calculation based on transit approximation
		3. notes, included text explaining further the variables
		4. added blender stuff for running via script window	
pb1 - 060826 - script fixes
pb1a/b - 060827 - working in gui.. found out can't
have scriptlink and gui at the same time, need file
anyway for defaults, decide to seperate. 
pc1 - 060828 - seperated out of sun-pc1.py
pc2 - 060828 - removed GUI, clean up
pc3 - 060829 - functional reading from file.
c - 060830 - almost release
0c - 060830 - fixing globals trying to fix bug
d - 060903 - release
'''


####################################################
# OPEN ISSUES
####################################################
''' 
0. fix DayOfTheYear to be exact
'''
####################################################
# THE INCLUDES
####################################################
import Blender
from Blender import *
from math import *
import os
import array


####################################################
## COPIED FROM GUI FILE ############################
####################################################
DFLTdata= {
	0: 89.600,	#long
	1: 27.483 ,	#lat
	2: 2006,		#year
	3: 1,				#month
	4: 1,				#day
	5: 0,				#hour
	6: 0.00,		#minute
	7: 0.00,		#orientation
	8: 20.00,		#multiplier
	9: 'Empty'	#empty name
}

n=len(DFLTdata)-1

## Set button variables (settings in the gui)
GUIdata = {
	0:Draw.Create(DFLTdata[0]),
	1:Draw.Create(DFLTdata[1]),
	2:Draw.Create(DFLTdata[2]),
	3:Draw.Create(DFLTdata[3]),
	4:Draw.Create(DFLTdata[4]),
	5:Draw.Create(DFLTdata[5]),
	6:Draw.Create(DFLTdata[6]),
	7:Draw.Create(DFLTdata[7]),
	8:Draw.Create(DFLTdata[8]),
	9:Draw.Create(DFLTdata[9])
}

scriptname = "sun__py"
FILE = None
fileblend = Blender.Get("filename")
filename = fileblend[:fileblend.rfind(".")] + "_blend-" + scriptname + "-control_data-DO_NOT_DELETE"+".dat"
FILEdata = {}#DFLTdata
txt =1 #number of text items
NAME='sun-0C.py'


####################################################
# FILE I/O
####################################################
## FILEOPEN
def fileopen():
	global scriptname, filename
	#print scriptname,":FILEOPEN"
	try:
		FILE = open(filename, "r")
		read()
	except IOError:
		pass
		
## READ	- functions, first item is a text item.
def read():
	global scriptname, GUIdata, FILEdata, n, txt
	i=0	
	FILE=open(filename,"r")
	while i<=n:
			x = FILE.readline()
			if i<=n-txt: 
					FILEdata[i] = float(x)
			else: 
				x.strip('\n')
				FILEdata[i]=eval(x)
			GUIdata[i].val = FILEdata[i]
			i=i+1
			startup=1
	FILE.close()

####################################################
####################################################
####################################################
'''
#write here start date
y = yNI.val #2006	#from 1901-2099
m = mNI.val #06    #from 1-12
day = dayNI.val #01  #from 0-31

#write here your position, you can find your position here
# http://www.heavens-above.com/countries.asp
lat = latNI.val #33 #58 #33 #57.717 #North is positive
long = longNI.val #97 #12 #97 #11.967 #East is positive

#how many minutes for one frame
multiplier = multiplierNI.val #20

#Name of your Empty object
empty_name = empty_nameTI.val #"Empty"

#Scene orientation in degrees clockwise, 
# an orientiation of 0degrees is due South when in top view (num7)
#
#topview [num7] with orientation at 0degrees:
#       N
#       |
#   W --+-- E
#       |
#       S
#
#topview [num7] with orientation at 90degrees:
#       W
#       |
#   S --+-- N
#       |
#       E
#
orientation = orientationNI.val #0

#typically these should not need to be changed
#hr = 0     #UTC correction from 0-23
mins = minsNI.val #00  #from 0-59
#adjustment to hr to account for UTC
hr = -long/15 + hrNI.val
'''

fileopen()

long =GUIdata[0].val
lat =GUIdata[1].val
y =GUIdata[2].val
m =GUIdata[3].val
day =GUIdata[4].val
hr =GUIdata[5].val
mins =GUIdata[6].val
orientation =GUIdata[7].val
multiplier =GUIdata[8].val
empty_name =GUIdata[9].val

hr = -long/15 + hr


###################################################
#and now some calculations
###################################################
frame = float(Get('curframe')-1)

minsp = mins+frame*multiplier
daysp = float(minsp)/1440
h = float(hr + mins/60 + minsp/60)

tpi = 2* pi
twopi = tpi
degs = 180 / pi
rads = pi / 180

#   Get the days to J2000
#   h is UT in decimal hours
#   FNday only works between 1901 to 2099 - see Meeus chapter 7
def FNday (y, m, d, h):
	days = 367 * y - 7 * (y + (m + 9) / 12) / 4 + 275 * m / 9 + d - 730531.5 + h / 24
	return float(days)

#   the function below returns the true integer part,
#   even for negative numbers
def FNipart(x):
	return int(sqrt(x*x))

#   the function below returns an angle in the range
#   0 to two pi
def FNrange(x):
    b = x / tpi
    a = tpi * (b - FNipart(b))
    if a < 0:  
			a = tpi + a
    return a

#   Find the ecliptic longitude of the Sun
#
def FNsun(d):
	L = FNrange(280.461 * rads + 0.9856474 * rads * d)  #   mean longitude of the Sun
	g = FNrange(357.528 * rads + 0.9856003 * rads * d)  #   mean anomaly of the Sun
	return FNrange(L + 1.915 * rads * sin(g) + 0.02 * rads * sin(2 * g))  #   Ecliptic longitude of the Sun

def rev(x):
	rv = x - int(x/360)*360
	if rv <0:
		rv = rv + 360
	return rv

d = FNday(y, m, day, h)

#>> 
# Hack which fixes the orientation based on solar transit time
# http://ww.srrb.noaa.gov/highlights/sunrise/solareqns.PDF
# http://en.wikipedia.org/wiki/Equation_of_time
#DayOfTheYear = date(y,m,day)  #.strftime("%j") #this attempt at an exact function is not working
DayOfTheYear = (m-1)*30+day #approximate
Bb = 2 * pi * (DayOfTheYear-81)/364
EqOfTime = 9.87 * sin(2*Bb)-7.53*cos(Bb)-1.5*sin(Bb)
Transit = 720+4*long-EqOfTime
#preorientation = Transit/(60*24)*360
#print preorientation
orientation = Transit/(60*24)*360-orientation-long-90
#<<

w = 282.9404 + 4.70935E-5 * d
a = 1.000000
e = 0.016709 - 1.151E-9 * d 
M = 356.0470 + 0.9856002585 * d
M = rev(M)

oblecl = 23.4393 - 3.563E-7 * d
L = rev(w + M)

E = M + degs * e * sin(M*rads) * (1 + e * cos(M*rads))

x = cos(E*rads) - e
y = sin(E*rads) * sqrt(1 - e*e)
r = sqrt(x*x + y*y)
v = atan2( y, x ) *degs
lon = rev(v + w)

xequat = r * cos(lon*rads) 
yequat = r * sin(lon*rads) * cos(oblecl*rads)
zequat = r * sin(lon*rads) * sin(oblecl*rads) 

RA = atan2(yequat, xequat)*degs / 15
Decl = asin(zequat / r) * degs

GMST0 = (L*rads + 180*rads) / 15 * degs
SIDTIME = GMST0 + h + long/15
HA = rev((SIDTIME - RA))*15

x = cos(HA*rads) * cos(Decl*rads)
y = sin(HA*rads) * cos(Decl*rads)
z = sin(Decl*rads)

xhor = x * sin(lat*rads) - z * cos(lat*rads)
yhor = y
zhor = x * cos(lat*rads) + z * sin(lat*rads)

azimuth = atan2(yhor, xhor)*degs + 180
altitude = atan2(zhor, sqrt(xhor*xhor+yhor*yhor))*degs

empty = Blender.Object.Get(empty_name)

x = 90
y = 90
z = 0

ax = azimuth/degs
az = altitude/degs

empty.RotZ = -ax+orientation/degs
empty.RotY = -az 

actualh = h % 24


####################################################
# DEBUG
####################################################
#print "azimuth= ", azimuth 
#print "altitude= ", altitude 
#print "actualh   = ",actualh-hr
#print "d         = ",d
#print "declination = ",Decl
#print " "