The key parts of this final project were as follows: 1) build interesting and complex 3D turtle shapes and 2) give some interactivity to the turtle 3D programs. In order to build 3D shapes, I first needed to make changes to turtle_interpreter and shapes files. Once I finished made those changes in the lab, I first needed to think about what shapes to build and how to build them.
1) Make at least four new 3D shape classes, like a box or a house. Use strings, just like you did for the square and triangle classes. You can use parameterized strings, which should make the task easier.
For task 1 and essentially my entire project, I created in total of 8 shapes:
- Rectangular prism with a triangular roof
- Rectangular prism with a trapezoid roof
- Octagonal prism
- Rectangular prism
- Octagonal prism with curve roof
- Octagonal pyramid
My shapes were all polygons because my plan was ultimately to build 3D Miller image based on my Colby scene from project 9 and 10.
Below are images of my 3D shapes with two different styles: first is normal; second is jitter. To obtain the images below, run the file task1.py with a command line argument, either normal or jitter.
(Required Image 1) (Required Image 1)
A star is simply a triangle rotated 72 degrees by 5 times. It looks like a 3D image because I rolled them.
The octagonal pyramid will represent the peak of Miller library; the concept of building it was very similar to building a square pyramid. I simply connected the opposite vertices by drawing upper-pointing triangles.
For rectangular prisms, octagonal prisms, and rectangular prisms with different shapes of roofs, I simply needed to calculate different angles to pitch.
Although the instruction for task 2 recommend to minimize the amount of code, I created this many of shapes in order to build 3D Miller library as complete as possible.
2) Make a 3D scene that incorporates your shapes. Your scene can be abstract, artistic, or realistic. Try to maximize the complexity of the scene, while minimizing the amount of code you have to write. For this task, spend some time thinking about your design before you start to code. Talk about your design in your writeup. Note that complexity may not mean lots of objects. Having lots of small stuff will slow down the interactive viewing.
As I said above, I ended up writing a decent-length of codes to build Miller library but I think my design of Miller library was efficient because I used minimum number of shapes to build it. My concept of building Miller library was essentially same as playing with a building a block. I started to design the foundations first: the building blocks, i.e. rectangular prisms. Then, I needed to come up with different roofs for those blocks. Next, I needed to decide how to build the top parts of Miller library. Following the real image of Miller library, I simply created octagonal prisms to build the top parts. For the peak of the library, I divided it into two blocks: a curved roof and octagonal pyramid.
The order of building was from the bottom to the top although the reverse sounds better. I did use a for loop once in order to draw the six pillars in the middle of the front of Miller library. I did not create a new shape class for those pillars; I simply modified the existing rectangular prism shape class to do so. I did the same thing for the triangular roof to adjust to the smaller prisms.
Another thing to note is that I made the style as a command line argument so that a user can observe the different among styles more easily (similar to what I did for the last project). Below are the two images of my 3D Miller library. The first one used 'normal' style, and the second one used 'jitter'. To obtain the images below, run the file task2.py with command line argument, either normal or jitter.
(Required Image 2)
(Required Image 3)
3) Do something interesting within this context. Make sure you have a clear description of the task. Design a solution you think will work and then implement the solution. The difficulty of the task is not necessarily as important as following a structured process so you understand what the computer needs to do and how to do it. The design of your solution should be part of your writeup. Note: you can choose something from the list of extensions, if you would like. If you are wondering how we will grade it, then keep this is mind: we don't simply count the number of extensions you do. We look at the quality. If this task allows you to do something spectacular, then it may get you over the 25/30 mark.
To make my 3D miller more interesting, I decided to three things. 1) use different style and color to make the building look nicer, 2) draw a 3D tree so that it looks more like my colby scene from the last project, and 3) draw 3D stars above the library, also because I had stars in my Colby scene. The first task was easy. I simply needed to use the shape class's methods: color() and setStyle(). The second task was also relatively easy. I first needed to edit my task5_2.txt lsystem and add some pitch and roll to make it look like a 3D tree. The last task was not as easy because I wanted to give some interactivity to drawing stars. I wanted to let users to draw stars as they click the right button of the mouse. Thus, I needed to take a look at turtleTk3D's method setRightMouseCallback(). Once I understood how it works, I created a function that draws a star at ranged-random locations and attached that function to the right button of the mouse. Below are my required images 4. The first one does not have any star. The second one does as I clicked the right button several times. To obtain the images below, run the file task3.py with command line argument 'brush' and task5_2.txt as the filename of lsystem. Click the right button to draw the stars.
(Required Image 4)
(Required Image 4)
- Pick some semi-complex shapes and create efficient designs for them. Wire frame geodesic spheres, or dodecahedrons, for example, are interesting shapes with lots of regularity to them.
In order to build a dodecahedron, I decided to design it in two steps. First, build the bottom half. Second, build the top half, rotate it, and put it on top of the bottom half. Designing the half of dodecahedron was the most difficult part of this project but once I figured the string, I was actually able to condense the string by using the for loop. Eventually, the string to draw a half of dodecahedron turned out to be quite simple with a lot of regularity. Below are the images. Run the file brainstorming.py and its function test3().
- Use the 3D turtle to create an interactive tool for creating L-systems. Take user input from the command line to define base strings and rules.
My extension is not as complete as the instruction says. Although it draws a system based on base string, rule string, angle, iteration number, and symbol on the command line, it cannot use parametrized L-system. The reason has to do with the way I building the replacement string. The way I approached this extension was to create a shape class that builds the final nstring based on the base and rule string in addition to angle, iteration number, and symbol. When I initialize the shape and draw it on another file, then the shape class gets information from the command line. To draw the first image below I typed brainstorming.py F+F+F+F+ FF 90 1 F. (it simply draws a square). For the second image, I typed F+F+F+F+ F-F+ 90 4 F. Make sure to run the function test() on the file brainstorming.py.
- The 3D turtle allows you to attach a function to the right mouse button. Whenever the user clicks the right mouse button in the window, the function gets called. How could you use this to make an interactive program? (Try running the 3D turtle python file directly and use the right mouse button, then look at the test method to see how it's done.)
Please refer to my explanation in task3 about this extension.
- Design a generic shape class that reads its string from a file. See if you can combine this with some interactivity so the user can edit a string and then look at the result immediately.
Although my generic shape class does not have the interactivity that enables the user to see the result immediately, it is able to read the information about string and angle from the text file. I created a class called Gshape that reads the information of the textile and then builds the string and angle.
To obtain the images below, I ran brainstorming.py and its function test2() and typed test.txt on the command line. For the first image, my base string was F+F+F+F+F+F+ and angle was 60. This will draw a hexagon. For the second image, my base string was F+F++F+F++ and angle was 60. This will draw a diamond shape.
Without any doubt, this project was the hardest CS project that I have ever done. I both enjoyed and disliked designing 3D shapes (if you know what I mean). One thing that still bothers me is that I was not able to figure out how to give interactivity to the user to see the result immediately.
Sources, imported libraries, and collaborators:
I imported following libraries: turtle_interpreter, turtleTk3D, shape, sys, random, tree, and lsystem. I received a lot of help from professor Skrien and Eaton. I did not reference any source in this project.