#!/usr/bin/python3
# ====================================================================
# Plot sine function with an offset origin
#
# An offset origin means the origin for the working X,Y coordinates
# is not in the center of the graphics window. The origin offset is
# specified as pixels from the left side of the graphics window
# (Xoffset) and from the bottom of the graphics window (Yoffset).
# Working (cartesian) coordinates must be converted to window
# coordinate for drawing.
#
# window coordinates working (cartesian) coordinates
#
# 0,0 +Y
# +--------- +X |
# | |
# | |
# | +------- +X
# +Y 0,0
#
# ====================================================================
import numpy as np
import graphics as gr
# --------------------------------------------------------------------
# ---- sine func
# --------------------------------------------------------------------
def sine_func(deg):
rad = np.deg2rad(deg)
y = np.sin(rad)
return y
# --------------------------------------------------------------------
# ---- range function for floats
# --------------------------------------------------------------------
def frange(start,end,inc):
while start < end:
yield start
start += inc
# --------------------------------------------------------------------
# ---- given working (cartesian) coordinates, calculate the offset
# ---- origin window coordinates. returned coordinates are integers.
# --------------------------------------------------------------------
def offset_xy(win,xoffset,yoffset,x,y):
##print(f'offset_xy({xoffset},{yoffset},{x},{y})')
wx = round(x + xoffset)
wy = round(win.height - y - yoffset)
##print(f'offset_xy returned x={wx}, y={wy}')
return (wx,wy)
# --------------------------------------------------------------------
# ---- draw X,Y offset axes
# --------------------------------------------------------------------
def draw_xy_offset_axes(win,xoffset,yoffset,linewidth=1,linecolor="black"):
# ---- window coordinates for offset origin
wx,wy = offset_xy(win,xoffset,yoffset,0,0)
# ---- X axis
xl = gr.Line(gr.Point(0,wy),gr.Point(win.width-1,wy))
xl.setWidth(linewidth)
xl.setFill(linecolor)
xl.draw(win)
# ---- Y axis
yl = gr.Line(gr.Point(wx,0),gr.Point(wx,win.height-1))
yl.setWidth(linewidth)
yl.setFill(linecolor)
yl.draw(win)
# --------------------------------------------------------------------
# ---- draw a point (small circle) using window coordinates
# --------------------------------------------------------------------
def draw_point(wx,wy,color='red',size=4):
p = gr.Circle(gr.Point(wx,wy),size)
p.setFill(color)
p.setOutline('black')
p.draw(win)
return p
# --------------------------------------------------------------------
# ---- main
# --------------------------------------------------------------------
if __name__ == '__main__':
# ---- graphics window size
window_height = 801
window_width = 801
# ---- offset origin in window coordinates
##xoffset = 400 # origin in center of graphics window
##yoffset = 400 # origin in center of graphics window
##xoffset = 600 # origin in upper right of graphics window
##yoffset = 600 # origin in upper right of graphics window
xoffset = 100 # origin in lower left of graphics window
yoffset = 300 # origin in lower left of graphics window
# ---- setup graphics window
win = gr.GraphWin('Sine Function w/ Offset Origin',
window_width,window_height)
win.setBackground("white")
# ---- draw X,Y axes offset
draw_xy_offset_axes(win,xoffset,yoffset)
# ---- plot sine function
# ---- X scale factor 0.5
# ---- Y scale factor 100
xmin = win.width
xmax = 0
ymin = win.height
ymax = 0
for deg in range(-720,721,18):
y = sine_func(deg)
x = deg * .5
y = y * 100
wx,wy = offset_xy(win,xoffset,yoffset,x,y)
draw_point(wx,wy)
if wx < xmin:
xmin = wx
if wx > xmax:
xmax = wx
if wy < ymin:
ymin = wy
if wy > ymax:
ymax = wy
print(f'Xmin = {xmin} Xmax = {xmax}')
print(f'Ymin = {ymin} Ymax = {ymax}')
# ---- pause program (click in window to continue)
click = win.getMouse()
win.close()