solution_050h.py

#!/usr/bin/python3
# ===================================================================
# draw a wire frame object's surfaces (in this case a cube)
#
# each surface has a different color. each surface is drawn in the
# order they appear in the surface list.
# ===================================================================

import coordinate_conversion as cc
import transformation_matrix as tm
import user_interface as ui
import draw_xy_axes as ax
import graphics as gr
import numpy as np
import re, os, platform, sys

win_height = 801               # window height  
win_width  = 801               # window width

# ---- each surface has a different color

surcolor= [ 'red','green','blue','cyan','yellow','white' ]

# ---- wire frame cube (points, lines, surfaces, normal vectors)
#
#         5+----------+6
#         /|         /|
#        / |        / |
#      1+----------+2 |
#       |  |       |  |
#       | 4+-------|--+7
#       | /        | /
#       |/         |/
#      0+----------+3
#
#
# ---- wire frame (cube) corner points
pts = [ (-50,-50,50),  (-50,50,50),             # point 0,1
        (50,50,50),    (50,-50,50),             # point 2,3
        (-50,-50,-50), (-50,50,-50),            # point 4,5
        (50,50,-50),   (50,-50,-50) ]           # point 5,7
#
# ---- pivot point
pivot = (0, 0, 0)
#
# ---- wire frame (cube) lines
lns = [ (pts[0],pts[1]), (pts[1],pts[2]),       # line 0,1
        (pts[2],pts[3]), (pts[3],pts[0]),       # line 2,3
        (pts[4],pts[5]), (pts[5],pts[6]),       # line 4,5
        (pts[6],pts[7]), (pts[7],pts[4]),       # line 6,7
        (pts[0],pts[4]), (pts[1],pts[5]),       # line 8,9
        (pts[2],pts[6]), (pts[3],pts[7]) ]      # line 10,11
#
# ---- wire frame (cube) surfaces
sur = [ (pts[0],pts[1],pts[2],pts[3]),          # surface 0  red
        (pts[4],pts[5],pts[6],pts[7]),          # surface 1  green
        (pts[4],pts[5],pts[1],pts[0]),          # surface 2  blue
        (pts[3],pts[2],pts[6],pts[7]),          # surface 3  cyan
        (pts[1],pts[5],pts[6],pts[2]),          # surface 4  yellow
        (pts[0],pts[3],pts[7],pts[4]) ]         # surface 5  white
#
# ---- wire frame (cube) normal vector for each surface
# ---- (points used to calculate normal vector)
nvec = [ (pts[0],pts[1],pts[2]),                # nv surface 0
         (pts[4],pts[5],pts[6]),                # nv surface 1
         (pts[4],pts[5],pts[1]),                # nv surface 2
         (pts[3],pts[2],pts[6]),                # nv surface 3
         (pts[1],pts[5],pts[6]),                # nv surface 4
         (pts[0],pts[3],pts[7]) ]              

# -------------------------------------------------------------------
# ---- draw surface
# -------------------------------------------------------------------

def draw_surface(win,pts,mtrx,color='red'):

    points = []                # list of points defining
                               # surface (polygon)

    # ---- create a list of graphics point
    # ---- (required by graphics polygon function)

    for p in pts:

        # ---- original coordinates (as an array)

        orgcord = np.array( [ p[0],p[1],p[2],1] )

        # ---- transform coordinates using transformation matrix

        newcord = mtrx @ orgcord

        # ---- convert new coordinates to window coordinates
        # ---- so the can be drawn

        x,y = cc.center_to_win_coords(newcord[0],newcord[1],
                                      win.width,win.height)

        # ---- add window coordinates to the list of graphics points

        points.append(gr.Point(x,y))

    # ---- draw the polygon using the list of graphics points

    pobj = gr.Polygon(points)
    pobj.setFill(color)
    pobj.draw(win)

   # ---- return the graphics object in case we need it later

    return pobj

# -------------------------------------------------------------------
# ---- draw surfaces
# ----
# ---- win    the window to draw in
# ---- sur    a list of the surfaces to be drawn
# ---- mtrx   transformation matrix
# -------------------------------------------------------------------

def draw_surfaces(win,sur,mtrx):

    i = 0                      # surface color index

    l = len(surcolor)          # length of color list

    for s in sur:              # for each surface

        if i >= l:             # end of color list?
            i = 0              # start over at 0

        draw_surface(win,s,mtrx,surcolor[i])

        i += 1                 # next color

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

# ---- running Python3?

if not ui.running_python3:
    print()
    print('Must run Python3 - exit program')
    print()
    sys.exit()

# ---- create drawing window

win = gr.GraphWin("Solid Object", win_width, win_height)
win.setBackground("white")

# ---- draw X,Y coordinate axes

ax.draw_xy_axes(win,True)

# ---- create transformation matrix

m0 = tm.get_identity_matrix_3d()
m1 = tm.get_x_rotation_matrix_3d(10)
m2 = tm.get_y_rotation_matrix_3d(20)
m3 = tm.get_z_rotation_matrix_3d(30)

mtrx = m3 @ m2 @ m3

# ---- draw (cube) surfaces

draw_surfaces(win,sur,mtrx)

# ---- pause program

ui.pause()