Welcome, guest | Sign In | My Account | Store | Cart
```#!/usr/bin/env python
# coding: UTF-8
#
## @package _12_tet
#
#  Draws a 3D tetrahedron and allows a user to rotate it
#  (mouse left button and wheel).
#
#  The Tetrahedron is represented by a 3 x 4 matrix.
#  Each column represents a 3D vertex.
#
#  note: a m x n matrix is represented by a list of lines:
#     [[l_1] [l_2] .. [l_m]].
#  m = len(mat), n = len(mat[0]), mat(i,j) = mat[i][j]
#
#  @author Paulo Roma
#  @since 01/05/2014
#  @see http://www.orimosenzon.com/wiki/index.php/Python_samples
#  @see http://mathworld.wolfram.com/RotationMatrix.html

try:
from tkinter import *     # python 3
except ImportError:
from Tkinter import *     # python 2
from math import *

def createZeroMat(m,n):
"""Return a matrix (m x n) filled with zeros."""

ret = [0] * m
for i in range(m):
ret[i] = [0] * n
return ret

def matMul(mat1, mat2):
"""Return mat1 x mat2 (mat1 multiplied by mat2)."""

m = len(mat1)
n = len(mat2[0])
common = len(mat2)

ret = createZeroMat(m,n)
if  len(mat1[0]) == len(mat2):
for i in range(m):
for j in range(n):
for k in range(common):
ret[i][j] += mat1[i][k] * mat2[k][j]
return ret

def matTrans(mat):
"""Return mat (n x m) transposed (m x n)."""

m = len(mat[0])
n = len(mat)

ret = createZeroMat(m,n)
for i in range(m):
for j in range(n):
ret[i][j] = mat[j][i]
return ret

def translate(x,y,dx,dy):
"""Translate vector(x,y) by (dx,dy)."""

return x+dx, y+dy

def drawTet(tet,col):
"""Draw a tetrahedron."""

w = canvas.winfo_width()/2
h = canvas.winfo_height()/2
canvas.delete(ALL) # delete all edges
nv = len(tet[0])   # number of vertices in tet (4)

# draw the 6 edges of the tetrahedron
for p1 in range(nv):
for p2 in range(p1+1,nv):
canvas.create_line(translate(tet[0][p1], tet[1][p1], w, h),
translate(tet[0][p2], tet[1][p2], w, h), fill = col)

def init():
"""Initialize global variables."""

global ROT_X, ROT_Y, ROT_Z
global eps, EPS, tet
global lastX, lastY, tetColor, bgColor

tet = matTrans([[0,-100,0],[-100,100,0],[100,100,0],[0,0,200]])

# counter-clockwise rotation about the X axis
ROT_X = lambda x: matTrans([[1,0,0],           [0,cos(x),-sin(x)], [0,sin(x),cos(x)] ])

# counter-clockwise rotation about the Y axis
ROT_Y = lambda y: matTrans([[cos(y),0,sin(y)], [0,1,0],            [-sin(y),0,cos(y)]])

# counter-clockwise rotation about the Z axis
ROT_Z = lambda z: matTrans([[cos(z),sin(z),0], [-sin(z),cos(z),0], [0,0,1]])

eps = lambda d: pi/300 if (d>0) else -pi/300
EPS = lambda d: d*pi/300

lastX = 0
lastY = 0
tetColor = 'black'
bgColor = 'white'

def cbClicked(event):
"""Save current mouse position."""

global lastX, lastY

lastX = event.x
lastY = event.y

def cbMottion(event):
"""Map mouse displacements in Y direction to rotations about X axis,
and mouse displacements in X direction to rotations about Y axis."""

global tet

# Y coordinate is upside down
dx = lastY - event.y
tet = matMul(ROT_X(EPS(-dx)),tet)

dy = lastX - event.x
tet = matMul(ROT_Y(EPS(dy)),tet)

drawTet(tet,tetColor)
cbClicked(event)

def wheelUp(event):
"""Map mouse wheel up displacements to rotations about Z axis."""

global tet
tet = matMul(ROT_Z(EPS(1)),tet)
drawTet(tet,tetColor)

def wheelDown(event):
"""Map mouse wheel down displacements to rotations about Z axis."""

global tet
tet = matMul(ROT_Z(EPS(-1)),tet)
drawTet(tet,tetColor)

def wheel(event):
"""Map mouse wheel displacements to rotations about Z axis."""

global tet
tet = matMul(ROT_Z(EPS(event.delta/120)),tet)
drawTet(tet,tetColor)

def resize(event):
"""Redraw the tetrahedron, in case of a window change due to user resizing it."""

drawTet(tet,tetColor)

def main():
global canvas
root = Tk()
root.title('Tetrahedron')
root.geometry('+0+0')

init()

canvas = Canvas(root, width=400, height=400, background=bgColor)
canvas.pack(fill=BOTH,expand=YES)
canvas.bind("<Button-1>", cbClicked)
canvas.bind("<B1-Motion>", cbMottion)
canvas.bind("<Configure>", resize)

from platform import uname
os = uname()[0]
if ( os == "Linux" ):
canvas.bind('<Button-4>', wheelUp)      # X11
canvas.bind('<Button-5>', wheelDown)
elif ( os == "Darwin" ):
canvas.bind('<MouseWheel>', wheel)      # MacOS
else:
canvas.bind_all('<MouseWheel>', wheel)  # windows

drawTet(tet,tetColor)

mainloop()

if __name__=='__main__':
sys.exit(main())
```

#### Diff to Previous Revision

```--- revision 1 2014-05-12 16:49:11
+++ revision 2 2014-05-14 21:03:40
@@ -2,11 +2,6 @@
# coding: UTF-8
#
## @package _12_tet
-#
-#  @author Paulo Roma
-#  @since 01/05/2014
-#  @see http://www.orimosenzon.com/wiki/index.php/Python_samples
-#  @see http://mathworld.wolfram.com/RotationMatrix.html
#
#  Draws a 3D tetrahedron and allows a user to rotate it
#  (mouse left button and wheel).
@@ -17,6 +12,11 @@
#  note: a m x n matrix is represented by a list of lines:
#     [[l_1] [l_2] .. [l_m]].
#  m = len(mat), n = len(mat[0]), mat(i,j) = mat[i][j]
+#
+#  @author Paulo Roma
+#  @since 01/05/2014
+#  @see http://www.orimosenzon.com/wiki/index.php/Python_samples
+#  @see http://mathworld.wolfram.com/RotationMatrix.html

try:
from tkinter import *     # python 3
@@ -146,7 +146,7 @@
"""Map mouse wheel displacements to rotations about Z axis."""

global tet
-    tet = matMul(ROT_Z(EPS(event.delta)),tet)
+    tet = matMul(ROT_Z(EPS(event.delta/120)),tet)
drawTet(tet,tetColor)

def resize(event):
```