Code Example: test_rotate_line.py

#! /usr/bin/python3
# ===================================================================
# rotate a line anchored at the origin (0,0)
# ===================================================================

import transformation_matrix as tm
import coordinate_conversion as cc
import user_interface as ui
from graphics import *
import numpy as np
import os, sys

win_width  = 801
win_height = 801


# -------------------------------------------------------------------
# ---- function: draw X,Y Cartesian coordinate axes
# -------------------------------------------------------------------

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)

# -------------------------------------------------------------------
# ---- replace comma and split
# -------------------------------------------------------------------

def replace_comma_and_split(s):

    lst = s.replace(',',' ').split()

    return lst

# -------------------------------------------------------------------
# ---- draw line segment (from the origin)
# -------------------------------------------------------------------

def draw_line_segment(win,ul,x1,y1,x2,y2,ends=True,
                      color1='black',color2='black'):
    wx1,wy1 = cc.center_to_win_coords(x1,y1,win.width,win.height)
    wx2,wy2 = cc.center_to_win_coords(x2,y2,win.width,win.height)
    l = Line(Point(wx1,wy1),Point(wx2,wy2))
    l.setWidth(2)
    l.setFill(color1)
    l.draw(win)
    ul.append(l)
    if ends:
        draw_point(win,ul,x1,y1,color2)
        draw_point(win,ul,x2,y2,color2)

# -------------------------------------------------------------------
# ---- draw point (small circle)
# -------------------------------------------------------------------

def draw_point(win,ul,x,y,color='red'):
    wx,wy = cc.center_to_win_coords(x,y,win.width,win.height)
    p = Circle(Point(wx,wy),4)
    p.setFill(color)
    p.draw(win)
    ul.append(p)

# -------------------------------------------------------------------
# ---- draw line segment (vector) using a rotation angle
# -------------------------------------------------------------------

def draw_rotation_angle(win,ul,ang,len=300):

    ta = tm.get_z_rotation_matrix_2d(ang)

    s = [300,0,1]
    xy = ta @ s

    draw_line_segment(win,ul,0,0,xy[0],xy[1])

    return ul

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

# ---- create window

win = GraphWin("vector from origin", win_width, win_height)
win.setBackground("white")

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

draw_xy_axes(win)

# ---- ask the user what to do

ul = []

while True:

    ui.clear_screen()

    print()
    print('options   description')
    print('-------   -----------')
    print('   1      enter X,Y coordinates (use a comma)')
    print('   2      enter rotation angle (degrees)')
    print('   3      clear the screen')
    print('   9      exit program')
    
    print()
    s = ui.get_user_input('enter selection ')

    # --- blank line
    if not s:
        continue

    # ---- convert input to an integer
    tf,i = ui.is_integer(s)
    if not tf:
        print()
        print(f'Bad input ({s})')
        ui.pause()
        continue

    if i == 1:
        print()
        s = ui.get_user_input(f'Enter X,Y coordinates ')
        lst = replace_comma_and_split(s)
        if len(lst) != 2:
            print()
            print(f'Bad input ({s})')
            ui.pause()
            continue
        tf,x = ui.is_integer(lst[0])   # X coordinate
        if not tf:
            print()
            print(f'Bad input ({s})')
            ui.pause()
            continue
        tf,y = ui.is_integer(lst[1])   # Y coordinate
        if not tf:
            print()
            print(f'Bad input ({s})')
            ui.pause()
            continue

    if i == 2:
        print()
        s = ui.get_user_input('Enter rotation angle (degrees) ')
        tf,a = ui.is_float(s)
        if not tf:
            print()
            print(f'Bad input ({s})')
            ui.pause()
            continue
        draw_rotation_angle(win,ul,a)
        ui.pause()
        continue

    if i == 3:
        for o in ul:
            o.undraw()
        ul = []
        continue

    if i == 9:
        break

    print()
    print(f'Bad input ({r}')
    ui.pause()
    continue

# ---- end program

win.close()
print()