Clock Face Using Only Window Coordinates

#! /usr/bin/python3
# ===================================================================
# draw a clock face with moving minute and hour hands using
# window coordinates and NO transformation matrix
#
# In order to see things happening, the clock hands do not move
# correctly. Making them move correctly is a task for the user.
# ===================================================================

from graphics import *
import numpy as np
import time

clock_center_x = 400                   # clock center
clock_center_y = 400                   # clock center
clock_radius   = 200                   # clock radius
ctxt_point     = Point(400,700)        # coordinate text point
hangle         = 0.0                   # hour hand angle
mtxt_point     = Point(400,100)        # message text point
win_width      = 801                   # window width
win_height     = 801                   # window height

# -------------------------------------------------------------------
# ---- function: draw X,Y axes (center of window)
# -------------------------------------------------------------------

def draw_xy_axes(win,line_width=1,line_color="black"):

    xl = Line(Point(0,win.height/2),Point(win.width-1,win.height/2))
    xl.setWidth(line_width)
    xl.setFill(line_color)
    xl.draw(win)

    yl = Line(Point(win.width/2,0),Point(win.width/2,win.height-1))
    yl.setWidth(line_width)
    yl.setFill(line_color)
    yl.draw(win)

# -------------------------------------------------------------------
# ---- main
# -------------------------------------------------------------------

# ---- create window

win = GraphWin("Clock Face", win_width, win_height)
win.setBackground("white")

# ---- draw center X,Y axes (Cartesian coordinate axes)

draw_xy_axes(win)

# ---- draw clock face

c = Circle(Point(clock_center_x,clock_center_y),200)
c.setWidth(4)
c.setOutline("black")
c.draw(win)

# ---- clock bounding box

bbx1 = clock_center_x - clock_radius
bbx2 = clock_center_x + clock_radius
bby1 = clock_center_y - clock_radius
bby2 = clock_center_y + clock_radius

##print(f'Bouding Box: ({bbx1},{bby1}),({bbx2},{bby2})') 

# ---- draw message

msg = 'Click inside the clock to exit\nClock runs faster than clock speed for demo'

mtxt = Text(mtxt_point,msg)
mtxt.setSize(18)
mtxt.setStyle('bold')
mtxt.draw(win)

# ---- draw moving minute and hour hands

ctxt       = None              # X,Y coordinate of Text object
hand_angle = 0                 # hand angle (deg)
mhand      = 180.0             # minute hand length
hhand      = 160.0             # hour   hand length
mobj       = None              # minute hand graphics object
hobj       = None              # hour   hand graphics object

while True:

    # ---- time to quit?

    mclk = win.checkMouse()    # mouse click?

    if mclk is not None:

        mx = mclk.getX()
        my = mclk.getY()

        txt = f'X = {mx}, Y = {my}'

        if ctxt is not None:
            ctxt.undraw()
        ctxt = Text(ctxt_point,txt)
        ctxt.draw(win)

        if mx > bbx1 and mx < bbx2 and my > bby1 and my < bby2:
            break

    # ---- draw minute hand

    ##print(f'minute hand angle={hand_angle}  mod={hand_angle % 6}') 

    if hand_angle % 6 == 0:

        x = mhand * np.sin(np.deg2rad(hand_angle))
        y = mhand * np.cos(np.deg2rad(hand_angle))

        if mobj is not None:
            mobj.undraw()

        mobj = Line(Point(clock_center_x,clock_center_y),
                    Point(clock_center_x + x,clock_center_y + y))
        mobj.setWidth(4)
        mobj.setFill("black")
        mobj.draw(win)

    # ---- draw hour hand

    ##print(f'hour i hand angle={hand_angle}  mod={hand_angle % 30}')

    if hand_angle % 30 == 0:

        x = hhand * np.sin(np.deg2rad(hand_angle))
        y = hhand * np.cos(np.deg2rad(hand_angle))

        if hobj is not None:
            hobj.undraw()

        hobj = Line(Point(clock_center_x,clock_center_y),
                    Point(clock_center_x + x,clock_center_y + y))
        hobj.setWidth(4)
        hobj.setFill("red")
        hobj.draw(win)

    # ---- increment hand angle 1 deg

    hand_angle -= 1

    # ---- suspend execution (0.1 seconds)

    time.sleep(0.1)

# ---- end program

win.close()
print()