Dear Gnomonists

Recently, there has been a small correspondence about Spider Dials. This 
message mainly concerns those who like to do all their gnomonic calculations 
programatically.

I attach a short text file that contains the routines needed to prepare spider 
curves for a horizontal dial with a gnomon of given thickness. Computer 
routines are usually language and implementation specific (as these are), but 
the logic and gnomonics provided are correct (or so I hope and pray). The 
language is Python, which is easily read and quite easily adaptable to any 
other language (e.g. Java).

For me, the advantage of using a programical approach is that I use the same 
program to prepare graphics files that can be sent to...
i) a laser engraver to make a cheap plywood maquette of my design to check 
things out
ii) a water jet cutting company to cut out the dial plate and gnomon
iii) a photo-etching company to create the dial.

I am current working on the routines to generate G-Code that can go direct to a 
CNC routing engraver. I would love to hear from anyone working on a similar 
approach.

Best wishes
Kevin

p.s anyone who wants the astronomical routines mentioned in the text file have 
only to ask!


# Here are two routines that I use to draw Spider Hour lines on horizontal 
dials.
# They are written in Python, which is easy to read and can be adapted to 
# any other language quite simply

# Items such as Latitude, Time Zone etc are prefixed by My_ . These are global 
variables
# The coordinate sysyem is x-axis East/West, y-axis North/South downwards

def Get_Point(Year,Month,Day,Hour,Minute,Second,The_radius):
        # This routine is for a horizontal dial with a gnomon of given 
thickness 
        # It returns an x-y coordinate of the intersection of...
        #       a gnomon's shadow line 
        #       a circle centred in the middle of the dial
        # Inputs are the Date and CIVIL Time and the radius of the circle

        # The routine calls Sunpos - a general purpose astronomical support 
routine 
        # based on the rigorous algorithms of Meeus' "Astronomical Algorithms", 
        # which provides (amongst other things) the Sun's True Hour Angle.
        # (the routines use temperature, pressure and height - far beyond the 
accuracy
        # requirements of this application, but computers calculate quickly 
these days....)

        Result    = Sunpos(My_Latitude_deg, My_Longitude_deg, 
My_Time_Zone,My_DST,
                                       Year, Month, Day, Hour,  Minute, Second,
                                       My_Temp,My_Press,My_Height)
                
#=========================================================================
                # Sunpos returns...
                # 0 RA_hrs
                # 1 Decl_deg
                # 2 Radius_Vector_AU
                # 3 EoT_Gnomon_Min
                # 4 GMST_hrs
                # 5 Alt_deg
                # 6 Azim_deg
                # 7 LHA_deg
                # 8 Sunrise_hrs
                # 9 Sunset_hrs
        # unpack the variable of the Result that I need
        HA_deg    = Result[7]
        HA_rad    = radians(abs(HA_deg))
        
        # Calculate the Hour Line Angle
        HLA_rad   = atan(tan(HA_rad) * sin(radians(abs(My_Latitude_deg))))
        if (HA_deg > 90 or HA_deg < -90) : HLA_rad = HLA_rad + pi
        HLA_deg   = degrees(HLA_rad)
 
        # My_Noon_Gap is the thickness of the gnomon, HNG = Half Noon Gap
        HNG = My_Noon_Gap/2. if (HLA_deg < -90 or HLA_deg > 90) else 
-My_Noon_Gap/2. 
 
        # Signer picks the correct of the two intersection points between line 
and circle
        Signer = 1 if HLA_deg < 90 else -1

        # this part just does the coordinate geometry to find the intersection 
of line with circle
        tanGamma = tan(HLA_rad)
        dd = My_Style_Foot_Posn * tanGamma - HNG
        aaa = 1 + tanGamma**2
        bbb = 2 * dd * tanGamma
        ccc = dd * dd - The_radius ** 2
        y1 = (-bbb + Signer * sqrt(bbb**2 - 4 * aaa * ccc)) / (2 * aaa)
        x1 = sqrt(The_radius**2 - y1**2)

        # Switch sets the x-coordinate depend whether morning or afternoon 
        Switch = 1 if HA_deg > 0 else (-1 if HA_deg < 0 else 0)
        if HA_deg <> 0. :    
                xxx = Switch * x1
                yyy = - y1 #  graphics system has +ve y down the screen
        else: # deals with Noon
                xxx = HNG
                yyy = -sqrt(The_radius**2 - HNG**2)
        return (xxx,yyy)
        
def Do_Spiders():
        # The routine calls two general purpose routines....
        # Julian_Day - which gives to the Julian Day Number for a given 
Year/MonthDay
        # Get_Date_Time_from_JD - which Year/Month/Day from a given Julian Date
        
        # The Loop to draw ALL of the Spider Lines
        # The_Civil_Mins is the time on your watch
        The_Civil_Mins = int(60 * My_Start_Hour) # an integer
        The_End_Minutes= int(60 * My_End_Hour)   # an integer
        The_Start_Day  = Julian_Day(My_Year,1,1)
        The_End_Day    = Julian_Day(My_Year,12,31)
        while The_Civil_Mins <= The_End_Minutes :
                # The Loop through each day of the year to generate ONE Spider 
Line
                The_Day    = The_Start_Day
                Start_line = True # a new graphic line will have to be initiated
                while The_Day <= The_End_Day :
                        # this cumbersome bit of code is because nu 
astronomical routine 
                        # uses the date in years/month/days and civil 
hours/mins/seconds as input
                        xyz    = Get_Date_Time_from_JD(The_Day)
                        YYYY   = xyz[0] 
                        MMMM   = xyz[1]
                        DDDD   = xyz[2]
                        HHHH   = The_Civil_Mins/60           # n.b. integer 
arithmetic
                        mmmm   = The_Civil_Mins - HHHH * 60  # n.b. integer 
arithmetic
                        SSSS   = 0
                        # get the radus appropriate for the date
                        Radius = My_Inner_Radius + float(The_Day)/366.* 
(My_Outer_Radius - My_Inner_Radius)

                        # Call the routine to get the next point along the 
Spider Line
                        pqr = Get_Point(YYYY,MMMM,DDDD,HHHH,mmmm,SSSS,Radius)
                        # Unpack the retuned variables
                        x = pqr[0]
                        y = pqr[1]
                        
                        # the actual creation of the Spider Line is probably 
specific to your 
                        # graphics or plotting package, 
                        # but will probably contain something like this...
                        if Start_line: # initiate a new graphic path
                                beginpath(x,y)
                                Start_line = False
                        else:            
                                lineto(x,y) # continue existing graphic path
 
                        # increment the day
                        The_Day += 1
                # The year is done, close the graphic path, but do not draw it 
yet
                abc = endpath(draw=False) 
                
                # what follows is specific to the equipment you might be using
                Line_Type = 0                               # 10 minute line
                if The_Civil_Mins % 30 == 0 : Line_Type = 1 # half-hour line
                if The_Civil_Mins % 60 == 0 : Line_Type = 2 # hour line
                
                if To_Laser_Engraver :
                        # constant line thickness, variable colour to engrave 
different depths
                        Line_Thickness = .001
                        if Line_Type == 0 : Line_Colour = Cyan
                        if Line_Type == 1 : Line_Colour = Blue
                        if Line_Type == 2 : Line_Colour = Magenta
                else : # to photo etching
                        # constant colour, variable line thickness to etch more 
depth
                        Line_Colour = Black
                        if Line_Type == 0 : Line_Thickness = 1
                        if Line_Type == 1 : Line_Thickness = 2
                        if Line_Type == 2 : Line_Thickness = 2.5
                
                # NOW DRAW THE GRAPHIC PATH
                drawpath(abc, fill=None, stroke= 
Line_Colour,strokewidth=Line_Thickness)

                # Increment the minutes to draw the next spider line
                The_Mins += 10

---------------------------------------------------
https://lists.uni-koeln.de/mailman/listinfo/sundial

Reply via email to