Coordinate Conversion w/ Offset Origin

File: coordinate_offset_conversion.py

#!/usr/bin/python3
# ====================================================================
# 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 graphics as gr

# --------------------------------------------------------------------
# ---- 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)

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

if __name__ == '__main__':

    # ---- draw X,Y axes with offset origin

    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)
        xaxis = gr.Text(gr.Point(win.width-40,wy),"X")
        xaxis.setSize(24) 
        xaxis.setStyle("bold")
        xaxis.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)
        yaxis = gr.Text(gr.Point(wx,+40),"Y")
        yaxis.setSize(24) 
        yaxis.setStyle("bold")
        yaxis.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        

    # ---- 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 = 100       # origin in lower left of graphics window

    # ---- setup graphics window

    win = gr.GraphWin('Offset Origin',801,801)

    # ---- draw X,Y axes (offset origin)

    draw_xy_offset_axes(win,xoffset,yoffset)

    # ---- draw a point (ofset origin)

    wx,wy = offset_xy(win,xoffset,yoffset,100,200)
    draw_point(wx,wy)

    # ---- pause program (click in window to continue)

    click = win.getMouse()
    win.close()