#!/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()