Question
######## # This is code to do draw some Platonic solids and rotate them in 3D # # This is intended to be run from
######## # This is code to do draw some Platonic solids and rotate them in 3D # # This is intended to be run from the command line in an X11 window, just type python plato.py # Currently it is set to draw the cube, but just change the last line when you've got another solid instead of Cube()... # ########
# I'm using a package for graphics I found on the internet written by John Zelle. It is very 2CV style! # For some documentation about it see: https://www.cs.swarthmore.edu/~adanner/cs21/s15/Labs/graphics.php
import graphics as gr import numpy as np from time import sleep
# And here are our vector and matrix modules
from vec import *
#### # This returns the 3x3 rotation matrix for given angles about x-, y- and z-axes
def RotationMx(xangle,yangle,zangle): rotationz = [[np.cos(zangle), -np.sin(zangle), 0.0], [np.sin(zangle), np.cos(zangle), 0.0], [0.0, 0.0, 1.0]] rotationy = [[np.cos(yangle), 0.0, -np.sin(yangle)], [0.0, 1.0, 0.0], [np.sin(yangle), 0.0, np.cos(yangle)]] rotationx = [[1.0, 0.0, 0.0], [0.0, np.cos(xangle), -np.sin(xangle)], [0.0, np.sin(xangle), np.cos(xangle)]] return Multiply(Multiply(rotationx, rotationy), rotationz)
#### # This returns the vertices of a cube in order so that if you connect the dots you get the frame... # You want the coordinates to be about a radius of 200 or so... # I didn't do this very carefully, I've got more "double edges" than strictly necessary, but it works! # Note the cube has 8 vertices, 12 edges and 6 faces. Its faces are squares.
def Cube(): vecs = [[-1,-1,-1],[1,-1,-1],[1,-1,1],[1,-1,-1],[1,1,-1],[1,1,1],[1,1,-1],[-1,1,-1],[-1,1,1],[-1,1,-1],[-1,-1,-1],[-1,-1,1],[-1,1,1],[1,1,1],[1,-1,1],[-1,-1,1]] return ScaleVecs(vecs, 200)
#### # Similar for tetrahedron # The tetrahedron is self-dual. It has 4 vertices, 6 edges and 4 faces which are equilateral triangles
def Tetrahedron(): v1 = [1,0,-1p.sqrt(2)] v2 = [-1,0,-1p.sqrt(2)] v3 = [0,1,1p.sqrt(2)] v4 = [0,-1,1p.sqrt(2)] vecs = [v1,v2,v3,v1,v4,v2,v3,v4] return ScaleVecs(vecs,300)
#### # Here is the octahedron. This is the dual of the cube, so it has a vertex in the center of each face of the cube. # The octahedron has 6 vertices, 12 edges and 8 faces each of which is an equilateral triangle.
def Octahedron(): vtop = [0,0,1] vbot = [0,0,-1] v1 = [1,0,0] v2 = [0,1,0] v3 = [-1,0,0] v4 = [0,-1,0] vecs = [vtop,v1,vtop,v2,vtop,v3,vtop,v4,v3,v2,v1,v4,vbot,v1,vbot,v3,vbot,v2] return ScaleVecs(vecs,300)
#### # Here is the icosahedron. It has one vertex at [0,0,sqrt(5)] and one at [0,0,-sqrt(5)]. Then it has 5 vertices arranged # in a regular pentagon around the z-axis at height z=1. One of these vertices is at [2,0,1] then the others are 360/5 = 72 # degrees intervals around the circle from that. Finally it has 5 vertices arranged in a regular pentagon # around the z-axis at height z=-1. One of these is at [-2,0,1] then the others are spaced at 72 degree intervals from that. # You could use a rotation matrix to rotate by 72 degrees = 2 np.pi / 5 radians around the z-axis to find these points! # Then you've got to put the vertices in order so that you get all 30 edges when you walk that circuit... # The icosahedron as 12 vertices, 30 edges and 20 faces, each of which is an equilateral triangle.
# YOU SHOULD CODE THIS ONE!
#### # Here is the dodecahedron. This is dual to the icosahedron so it has a vertex in the center of each face of the icosahedron # It has 12 vertices, 22 edges and 12 faces, each of which is a pentagon
# DO THIS ONE TOO IF YOU CAN BUT NOT REQUIRED!
#### # This returns a polygon object with the given coordinates from the graphics package # Then to plot that polygon you do p.draw(win) where win is a graphics window # Note your vecs are probably in R^3 or R^4, it just takes the orthogonal projection to the xy-plane # Also color is a string 'red' 'blue' etc...
def DotToDot(vecs, color): points = [] for vec in vecs: points.append(gr.Point(vec[0],vec[1])) poly = gr.Polygon(points) poly.setOutline(color) return poly
#### # Here is the main function to animate your shape!
def RotatingShape(shape, name, color): # Create a window for drawing stuff in, 1001x1001 pixels win = gr.GraphWin(name, 1601, 1001) # Make the lower left pixel (-800,-500) and upper right (800,500) so origin is in the middle win.setCoords(-800,-500,800,500) # Set the background color to black win.setBackground('black') text = gr.Text(gr.Point(-350,-470), 'Select this window and press escape to exit') text.setTextColor('white') text.draw(win)
# Set up a matrix to do a little rotation rotationmatrix = RotationMx(np.pi / 720, np.pi / 360, np.pi / 1080)
# Draw the initial version of the cube frame = DotToDot(shape, color) frame.draw(win)
# Now loop until the user presses escape, rotating cube then redrawing it... while win.checkKey() != 'Escape': shape = MxTimesVecs(rotationmatrix, shape) newframe = DotToDot(shape, color) sleep(0.01) frame.undraw() newframe.draw(win) frame = newframe
# Tidy up at the end! win.close() return
#### # This is intended to be run from the command line inside an X11 terminal on CoCalc, type python plato.py # The first three shapes are coded, the last two are not yet...
RotatingShape(Tetrahedron(), 'Tetrahedron', 'yellow') RotatingShape(Cube(), 'Cube', 'cyan') RotatingShape(Octahedron(), 'Octahedron', 'orange') # RotatingShape(Icosahedron(), 'Icosahedron', 'white') # RotatingShape(Dodecahedron(), 'Dodecahedron', 'magenta')
# ONE LAST THING: I found when testing the code that sometimes the graphics window didn't appear because some # escape keys where stuck in the input buffer. When that happened I had to close down the X11 terminal and start # again...
The problem is to edit the file "plato.py" in your CoCalc folder to add a new function "Icosahedron()". Then uncomment the line at the end of the file that calls this function. When you run "python plato.py" from an X11 terminal and press escape a few times you should get your icosahedron being rotated after with the first three platonic solids. (If you're really into this you could do the final platonic solid, the dodecahedron too--optional!) All the function Icosahedron() has to do is return a list of vectors in R^3 (scaled at about the right scale so the radius is around 200) so that if you join up those vectors in order you get all of the edges of an icosahedron plotted... It doesn't matter if the list involves going over some edges twice, you'll probably have to do that it is a bit inefficient but it works!). Note the icosahedron has 30 edges so your list of vectors will be quite long. See the others I already coded for ideas. The main thing you'll need is to understand how to find the coordinates of the 12 vertices: --There's one at the top at coordinate (0,0,sqrt(5)). --There's one at the bottom at coordinate (0,0,-sqrt(5)). --Then there are five arranged in a regular pentagon center at (0,0,1) in the plane z=1. One of these five is at (2,0,1), then you can get the others by rotating that through 2 pi/ 5 radians around the z-axis, which you could do by multiplying by the rotation matrix returned by the function Rotation Mx(0,0,2 np.pi/ 5) that is already available in plato.py. --Finally there are five arranged in a regular pentagon center at (0,0,-1) in the plane z=-1. One of these five is at (-2,0,-1), then you can get the others by rotating that through 2 pi / 5 radians around the z-axis. ASK ME FOR HELP IF STUCK! This isn't as hard as it sounds at first. The problem is to edit the file "plato.py" in your CoCalc folder to add a new function "Icosahedron()". Then uncomment the line at the end of the file that calls this function. When you run "python plato.py" from an X11 terminal and press escape a few times you should get your icosahedron being rotated after with the first three platonic solids. (If you're really into this you could do the final platonic solid, the dodecahedron too--optional!) All the function Icosahedron() has to do is return a list of vectors in R^3 (scaled at about the right scale so the radius is around 200) so that if you join up those vectors in order you get all of the edges of an icosahedron plotted... It doesn't matter if the list involves going over some edges twice, you'll probably have to do that it is a bit inefficient but it works!). Note the icosahedron has 30 edges so your list of vectors will be quite long. See the others I already coded for ideas. The main thing you'll need is to understand how to find the coordinates of the 12 vertices: --There's one at the top at coordinate (0,0,sqrt(5)). --There's one at the bottom at coordinate (0,0,-sqrt(5)). --Then there are five arranged in a regular pentagon center at (0,0,1) in the plane z=1. One of these five is at (2,0,1), then you can get the others by rotating that through 2 pi/ 5 radians around the z-axis, which you could do by multiplying by the rotation matrix returned by the function Rotation Mx(0,0,2 np.pi/ 5) that is already available in plato.py. --Finally there are five arranged in a regular pentagon center at (0,0,-1) in the plane z=-1. One of these five is at (-2,0,-1), then you can get the others by rotating that through 2 pi / 5 radians around the z-axis. ASK ME FOR HELP IF STUCK! This isn't as hard as it sounds at firstStep by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started