#! /usr/bin/python3 # =================================================================== # demonstrate translation/rotation of a graphics object made # of line segments and points # =================================================================== import numpy as np import user_interface as ui import draw_xy_axes as ax import transformation_matrix as tm import coordinate_conversion as cc from two_vector_angle import two_vector_angle from graphics import * # ---- object (line segments) segs = [ ( 200.0, 200.0, 200.0,-200.0), ( 200.0,-200.0,-200.0,-200.0), (-200.0,-200.0,-200.0, 50.0), (-200.0, 50.0,-200.0, 200.0), (-200.0, 200.0,-100.0, 200.0), (-100.0, 200.0, 200.0, 200.0), ] # ---- fold line (line segment) fln = (-200.0,50.0,-100.0,200.0) # ---- test rotation angle (this is the angle between the # ---- Y axis and the fold line) # ------------------------------------------------------------------- # ---- draw line segment # ------------------------------------------------------------------- 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 object (made of line segments) # ---- segs object line segments # ---- fln fold line segment # ---- cnt draw fold line center point # ------------------------------------------------------------------- def draw_object(win,segs,fln,cnt=True): # ---- undraw list ul = [] # ---- draw object for s in segs: draw_line_segment(win,ul,s[0],s[1],s[2],s[3]) # ---- draw fold line if fln is not None: draw_line_segment(win,ul,fln[0],fln[1],fln[2],fln[3], True,'red','white') # ---- draw fold line center point if cnt: x = (fln[0]+fln[2])/2 y = (fln[1]+fln[3])/2 draw_point(win,ul,x,y,'white') return ul # ------------------------------------------------------------------- # ---- rotate/translate a list of line segments # ------------------------------------------------------------------- def translate_rotate_segs(x,y,ang,segs_old=None): segs_new = [] for seg in segs_old: seg_new = translate_rotate_seg(x,y,ang,seg) segs_new.append(seg_new) return segs_new # ------------------------------------------------------------------- # ---- rotate/translate a line segment # ------------------------------------------------------------------- def translate_rotate_seg(x,y,ang,seg): # ---- create a transformation matrix to: # ---- 1. move fold line center to the origin (0,0) # ---- 2. rotate fold line until vertical t1 = tm.get_translation_matrix_2d(x,y) tx = t1 if ang is not None: t2 = tm.get_z_rotation_matrix_2d(ang) tx = t2 @ t1 xy = [seg[0],seg[1],1] xy1 = tx @ xy xy = [seg[2],seg[3],1] xy2 = tx @ xy return (xy1[0],xy1[1],xy2[0],xy2[1]) # ------------------------------------------------------------------- # ---- main # ------------------------------------------------------------------- if __name__ == '__main__': win_width = 801 win_height = 801 # ---- create window win = GraphWin("Test Fold",win_width,win_height) win.setBackground("white") # ---- draw axes ax.draw_xy_axes(win,True) # ---- draw the object, etc. ul = draw_object(win,segs,fln) # ---- calculate the middle of the fold line x_fln = (fln[0]+fln[2])/2 y_fln = (fln[1]+fln[3])/2 # ---- create a test rotation angle r60 = np.deg2rad(60) # deg -> rad x = np.cos(r60) * 10 # X expand y = np.sin(r60) * 10 # Y expand v1 = [0.0,10.0] # Y axis v2 = [x,y] # fold line test_rad = two_vector_angle(v1,v2) # radians test_angle = np.rad2deg(test_rad) # degrees # ---- rotate/translate the line segments, etc. # ---- put the center of the fold line at the origin (0,0) print() print('translate/rotate object, etc.') ui.pause() for o in ul: o.undraw() ####segs_new = \ ####translate_rotate_segs(-x_fln,-y_fln,None,segs) ####fln_new = \ ####translate_rotate_seg(-x_fln,-y_fln,None,fln) segs_new = \ translate_rotate_segs(-x_fln,-y_fln,test_angle,segs) fln_new = \ translate_rotate_seg(-x_fln,-y_fln,test_angle,fln) ul = draw_object(win,segs_new,fln_new) # ---- restore the object, etc. # ---- put them back where they came from print() print('restore the original object, etc.') ui.pause() for o in ul: o.undraw() ####segs_restore = \ ####translate_rotate_segs(x_fln,y_fln,None,segs_new) ####fln_restore = \ ####translate_rotate_seg(x_fln,y_fln,None,fln_new) segs_restore = \ translate_rotate_segs(x_fln,y_fln,-test_angle,segs_new) fln_restore = \ translate_rotate_seg(x_fln,y_fln,-test_angle,fln_new) ul = draw_object(win,segs_restore,fln_restore) # ---- end program print() print('exit the program') ui.pause() win.close() print()