Sun Angle Script
The following rhinoscript code calculates and draws a series of sun angles based on the time, day and latitude.
NOTE: in my test there’s something happening to the angles around noon causing them to be inaccurate because the calculations are based on cos values. All other times besides noon should be fine.
Updated version with nicer UI from Ezio. Thank you!
Download:sunbatchrender_ezb.rvb
Option Explicit
'Script written by cwwang.com augmented by algorithmicdesign.net
'Script version Sunday, March 01, 2009 9:39:09 PM
Call Main()
Sub Main()
Dim i,j,k
Dim hour
Dim arrSettings : arrSettings = getSunSettings()
Dim longitude : longitude = CDbl(arrSettings(0))
Dim latitude : latitude = CDbl(arrSettings(1))
Dim offset : offset = CDbl(arrSettings(2))
'day number --> January 1 = day 1, January 2 = day 2, etc.
'March equinox 78
'September equinox 264
'June solstice 171
'Dec solstice 354
Dim startDay : startDay = CDbl(arrSettings(3))
Dim endDay : endDay = CDbl(arrSettings(4))
Dim dayIncrement: dayIncrement = CDbl(arrSettings(5))
Dim startHour : startHour = CDbl(arrSettings(6))
Dim endHour : endHour = CDbl(arrSettings(7))
Dim increment : increment = CDbl(arrSettings(8))
'Dim increment : increment =.1666666666666666666666666666666' 10/60=.16666 every ten minutes
'Dim increment : increment =.01666666666666666666666666666666' 1/60=.016666 every minute
Dim pathFolder : pathFolder = Rhino.BrowseForFolder(,"Pick a destination folder", "Output Folder")
Dim nTimes : nTimes =(endHour-startHour)/increment
Dim nDays : nDays =(endDay-startDay)/dayIncrement
ReDim analemmaPoints(CInt(nTimes),CInt(nDays))
'ReDim analemmaPoints(150,50)
Call Rhino.EnableRedraw(False)
Dim count:count=0
For i=startDay To endDay
Dim count2:count2=0
Dim paz:paz=0
Dim switchaz:switchaz=False
hour=startHour
For k=0 To (endHour-hour)/increment
Dim N:N=i
Dim g:g = (360/365.242199)*(N + hour/24.0)
'Rhino.Print(g)
'calculation of the declination of the sun
Dim D:D = 0.396372-22.91327*cos(Rhino.ToRadians(g))+4.02543*sin(Rhino.ToRadians(g))-0.387205*cos(Rhino.ToRadians(2*g))+0.051967*sin(Rhino.ToRadians(2*g))-0.154527*cos(Rhino.ToRadians(3*g)) + 0.084798*sin(Rhino.ToRadians(3*g))
'Rhino.Print("Declination "&d)
'calculate the time correction For solar angle:
Dim TC:TC = 0.004297+0.107029*cos(Rhino.ToRadians(g))-1.837877*sin(Rhino.ToRadians(g))-0.837378*cos(Rhino.ToRadians(2*g))-2.340475*sin(Rhino.ToRadians(2*g))
'Rhino.Print("Time Correction " &tc)
'calculate the Solar Hour Angle (SHA)
Dim SHA:SHA = (hour+offset-12)*15 + Longitude + TC
'rhino.Print("Solar Hour Angle "&sha)
'Note that If SHA Is greater than 180, Then you must add (-360) To the
'result And If SHA Is lower than -180, Then you must add 360 To the
If (SHA>180) Then
SHA=SHA-360
ElseIf(SHA<-180)Then
SHA=SHA+360
End If
'calculate the Sun Zenith Angle (SZA):
Dim SZA:SZA = (sin(Rhino.ToRadians(Latitude))*sin(Rhino.ToRadians(D)) )+ (cos(Rhino.ToRadians(Latitude))*cos(Rhino.ToRadians(D))*cos(Rhino.ToRadians(SHA)))
'rhino.Print("cos(sza) "&sza)
'NOTE: If cos(SZA) formula gives a figure greater than 1 use 1 And If
'it gives you a figure lower than -1 use -1.
'Dim SSZA:SSZA=SZA
If(SZA>=1) Then
SZA=1
ElseIf(SZA<=-1) Then
SZA=-1
End If
sza=ArcCos(sza)
'SZA Is the complementary angle of the Sun Elevation Angle Or
Dim sea:sea=90-sza
'calculate the Azimuth Angle (AZ):
Dim AZ
AZ = (sin(Rhino.ToRadians(D))-sin(Rhino.ToRadians(Latitude))*cos(Rhino.ToRadians(SZA) ) )/(cos(Rhino.ToRadians(Latitude))*sin(Rhino.ToRadians(SZA)))
az=arccos(az)
If(paz>az And switchaz=False)Then
switchAz=True
End If
paz=az
If(switchaz=True)Then
az=0-az
End If
'rhino.Print("Azimuth Angle "& az)
'rhino.Print("Zenith Angle "& sza)
'rhino.Print("Altitude Angle "& sea)
Dim ray:ray=Rhino.AddLine( Array(0,0,0),array(0,40,0) )
ray= Rhino.RotateObject(ray,array(0,0,0),sea,array(1,0,0),False)
ray= Rhino.RotateObject(ray,array(0,0,0),az,array(0,0,-1),False)
analemmaPoints(count2,count)=rhino.CurveEndPoint(ray)
Dim sun : sun = Rhino.AddDirectionalLight (rhino.CurveEndPoint(ray), rhino.CurveStartPoint(ray))
Call BatchRender(i, k, pathFolder)
Call Rhino.DeleteObject(sun)
'Call rhino.AddText(cstr(hour),analemmaPoints(count),.04)
count2=count2+1
hour=hour+increment
'Rhino.Print(hour)
Next
i=i+dayIncrement
count=count+1
Next
'Call rhino.AddLine(analemmaPoints(0,0),analemmaPoints(0,1) )
For i=0 To count2-1
For j=0 To count-2
'Dim analemmaCurve:analemmaCurve=rhino.AddCurve(analemmaPoints(3),4 )
Call rhino.AddLine(analemmaPoints(i,j),analemmaPoints(i,j+1) )
Next
Next
Call Rhino.EnableRedraw(True)
Rhino.Print("---")
End Sub
Function ArcCos(ByVal X)
If X <> 1 Then
ArcCos =rhino.ToDegrees( Atn(-X / Sqr(-X * X + 1)) + 2 * Atn(1) )
Else
ArcCos = 0
End If
End Function
Sub BatchRender(strDay, strHour, pathFolder)
Dim FileName : FileName = Chr(34) & pathFolder & strDay & "_" & strHour & ".jpg" & Chr(34)
Rhino.Command "-_Render "
Rhino.Command "-_SaveRenderWindowAs " & FileName & " _Enter"
Rhino.Command "-_CloseRenderWindow "
End Sub
Function getSunSettings()
getSunSettings = Null
Dim arrSettings(8), arrPrompt(8)
arrPrompt(0) = "Longitude"
arrPrompt(1) = "Latitude"
arrPrompt(2) = "GMT"
arrPrompt(3) = "StartDay"
arrPrompt(4) = "EndDay"
arrPrompt(5) = "DayIncrement"
arrPrompt(6) = "StartHour"
arrPrompt(7) = "EndHour"
arrPrompt(8) = "HourIncrement"
arrSettings(0) = Rhino.GetSettings(Rhino.InstallFolder & "SunRender.ini", "SunRender", arrPrompt(0))
If IsNull(arrSettings(0)) Then arrSettings(0) = -73.997
arrSettings(1) = Rhino.GetSettings(Rhino.InstallFolder & "SunRender.ini", "SunRender", arrPrompt(1))
If IsNull(arrSettings(1)) Then arrSettings(1) = 40.73
arrSettings(2) = Rhino.GetSettings(Rhino.InstallFolder & "SunRender.ini", "SunRender", arrPrompt(2))
If IsNull(arrSettings(2)) Then arrSettings(2) = 5
arrSettings(3) = Rhino.GetSettings(Rhino.InstallFolder & "SunRender.ini", "SunRender", arrPrompt(3))
If IsNull(arrSettings(3)) Then arrSettings(3) = 0
arrSettings(4) = Rhino.GetSettings(Rhino.InstallFolder & "SunRender.ini", "SunRender", arrPrompt(4))
If IsNull(arrSettings(4)) Then arrSettings(4) = 1
arrSettings(5) = Rhino.GetSettings(Rhino.InstallFolder & "SunRender.ini", "SunRender", arrPrompt(5))
If IsNull(arrSettings(5)) Then arrSettings(5) = 5
arrSettings(6) = Rhino.GetSettings(Rhino.InstallFolder & "SunRender.ini", "SunRender", arrPrompt(6))
If IsNull(arrSettings(6)) Then arrSettings(6) = 6.0
arrSettings(7) = Rhino.GetSettings(Rhino.InstallFolder & "SunRender.ini", "SunRender", arrPrompt(7))
If IsNull(arrSettings(7)) Then arrSettings(7) = 18.0
arrSettings(8) = Rhino.GetSettings(Rhino.InstallFolder & "SunRender.ini", "SunRender", arrPrompt(8))
If IsNull(arrSettings(8)) Then arrSettings(8) = 1
'Dim increment : increment =.1666666666666666666666666666666' 10/60=.16666 every ten minutes
'Dim increment : increment =.01666666666666666666666666666666' 1/60=.016666 every minute
'day number --> January 1 = day 1, January 2 = day 2, etc.
'March equinox 78
'September equinox 264
'June solstice 171
'Dec solstice 354
Dim arrReturnSettings : arrReturnSettings = Rhino.PropertyListBox (arrPrompt, arrSettings, "Please enter the appropriate values" ,"Sun Batch Render Settings")
Dim i
For i = 0 To Ubound(arrSettings)
'write these settings to a file so that you don't have to re-enter them next time
Rhino.SaveSettings Rhino.InstallFolder & "SunRender.ini", "SunRender", arrPrompt(i), arrReturnSettings(i)
Next
getSunSettings = arrReturnSettings
End Function
- Published:
- 02.28.09 / 3pm
- Category:
- Rhinoscript, Software
- Related: [Align to Point Rhinoscript][Grass 01][Grass: Brush]
3 Comments