#!/usr/bin/python3
# ===================================================================
# googly eyes - centered around the center of the window
#
# Note:
# 1. all coordinates are window coordinates with the origin
# (0,0) in the upper left corner of the window
# 2. window x increases right and window y increases down
# 3. window pixels have integer coordinates
# ===================================================================
import math
import numpy
import graphics as gr
eye_color = 'white'
iris_color = 'black'
# ---- window coordinates
win_width = 800
win_height = 800
win_x_center = round(win_width/2)
win_y_center = round(win_height/2)
eye_radius = 100
eye_distance = 2*eye_radius + 100 # distance between center of eyes
left_eye_x_center = win_x_center - round(eye_distance/2)
left_eye_y_center = win_y_center
right_eye_x_center = win_x_center + round(eye_distance/2)
right_eye_y_center = win_y_center
iris_radius = eye_radius/4
iris_distance = eye_radius/2
# Note: iris_distance is the distance from the center of the
# eye to the center of the iris. this is a fixed distance
# for all irises.
reset_button = [1, 1,80, 30]
exit_button = [81,1,161,30]
click_coords = [1,31,161,60]
# -------------------------------------------------------------------
# create eyes and irises
# -------------------------------------------------------------------
def create_eyes(win):
# ---- left eye
lex = win_x_center - int(eye_distance/2) # left eye x
ley = win_y_center # left eye y
c = gr.Circle(gr.Point(lex,ley),eye_radius)
c.setFill(eye_color)
c.setOutline('black')
c.setWidth(2)
c.draw(win)
# ---- right eye
rex = win_x_center + int(eye_distance/2) # right eye x
rey = win_y_center # right eye y
c = gr.Circle(gr.Point(rex,rey),eye_radius)
c.setFill(eye_color)
c.setOutline('black')
c.setWidth(2)
c.draw(win)
# ---- left iris
li = gr.Circle(gr.Point(lex,ley),iris_radius)
li.setFill(iris_color)
li.draw(win)
# ---- right iris
ri = gr.Circle(gr.Point(rex,rey),iris_radius)
ri.setFill(iris_color)
ri.draw(win)
return (li,ri)
# --------------------------------------------------------------------
# reset the eye's irises
# --------------------------------------------------------------------
def reset_irises(win,irises):
# ---- left iris reset
p = irises[0].getCenter()
x = p.getX()
y = p.getY()
dx = left_eye_x_center - x
dy = left_eye_y_center - y
irises[0].move(dx,dy)
# ---- left iris reset
p = irises[1].getCenter()
x = p.getX()
y = p.getY()
dx = right_eye_x_center - x
dy = right_eye_y_center - y
irises[1].move(dx,dy)
return
# -------------------------------------------------------------------
# move irises for testing
# -------------------------------------------------------------------
def test_move_irises(win,irises,dx=None,dy=None):
if dx is None:
dx = 40
if dy is None:
dy = 40
irises[0].move(dx,dy)
irises[1].move(-dx,-dy)
# -------------------------------------------------------------------
# move irises
# -------------------------------------------------------------------
# remember:
# 1. window x increases right and window y increases down
# 2. window pixels have integer coordinates
# -------------------------------------------------------------------
def focus_irises(irises,clickx,clicky):
# ---- click-point to center-of-left-eye (triangle hypotenuse)
dx = clickx - left_eye_x_center
dy = clicky - left_eye_y_center
h = math.sqrt(dx**2 + dy**2)
# ---- left eye iris new coordinates using similar triangles
newx = (dx/h * iris_distance) + left_eye_x_center
newy = (dy/h * iris_distance) + left_eye_y_center
# left eye iris old coordinates
oldx = irises[0].getCenter().getX()
oldy = irises[0].getCenter().getY()
# move left eye iris
irises[0].move(round(newx-oldx),round(newy-oldy))
# ---- click-point to center-of-right-eye (triangle hypotenuse)
dx = clickx - right_eye_x_center
dy = clicky - right_eye_y_center
h = math.sqrt(dx**2 + dy**2)
# ---- right iris new coordinates using similar triangles
newx = (dx/h * iris_distance) + right_eye_x_center
newy = (dy/h * iris_distance) + right_eye_y_center
# right eye iris old coordinates
oldx = irises[1].getCenter().getX()
oldy = irises[1].getCenter().getY()
# move right eye iris
irises[1].move(round(newx-oldx),round(newy-oldy))
# -------------------------------------------------------------------
# ---- draw buttons
# -------------------------------------------------------------------
def draw_buttons(win):
# ---- reset button
b1 = gr.Rectangle(gr.Point(reset_button[0],reset_button[1]),
gr.Point(reset_button[2],reset_button[3]))
b1.setOutline('black')
b1.setWidth(2)
b1.draw(win)
b1txt = gr.Text(b1.getCenter(),"RESET")
b1txt.setStyle("bold")
b1txt.draw(win)
# ---- exit button
b2 = gr.Rectangle(gr.Point(exit_button[0],exit_button[1]),
gr.Point(exit_button[2],exit_button[3]))
b2.setOutline('black')
b2.setWidth(2)
b2.draw(win)
b1txt = gr.Text(b2.getCenter(),"Exit")
b1txt.setStyle("bold")
b1txt.draw(win)
# ---- click coordinates
ck = gr.Rectangle(gr.Point(click_coords[0],click_coords[1]),
gr.Point(click_coords[2],click_coords[3]))
ck.setOutline('black')
ck.setWidth(2)
ck.draw(win)
return ck
# -------------------------------------------------------------------
# ---- main
# -------------------------------------------------------------------
if '__main__' == __name__:
# ---- create graphics window
win = gr.GraphWin("Googly Eyes", win_width, win_height)
ck = draw_buttons(win)
# ---- draw googly eyes
irises = create_eyes(win)
# ---- initial click text
cktxt = gr.Text(ck.getCenter(),f'click coords')
cktxt.setStyle("bold")
cktxt.draw(win)
# ---- main graphics loop
while(True):
click = win.getMouse()
x = click.getX()
y = click.getY()
# ---- in reset button?
if (x > reset_button[0]) and (x < reset_button[2]) and \
(y > reset_button[1]) and (y < reset_button[3]):
##print('Reset')
reset_irises(win,irises)
continue
# ---- in exit button?
if (x > exit_button[0]) and (x < exit_button[2]) and \
(y > exit_button[1]) and (y < exit_button[3]):
##print('Exit')
break
# ---- report click coords
##print(f'x = {x}, y = {y}')
cktxt.undraw()
cktxt.setText(f'x = {x}, y = {y}')
cktxt.draw(win)
##test_move_irises(win,irises)
# ---- focus irises on clicked coordinates
focus_irises(irises,x,y)
win.close() # Close window when done