The purpose of today's lab is to familiarize you with VPython and to experiment with 2D and 3D graphics (even though we haven't discussed 3D in class yet). You should create a lab11 subdirectory inside your cs120 directory and work there (that is, you should save all of your programs there). You might want to use the desktop switching feature of Linux to read this lab on one desktop and run idle on the other. (Using VPython with IDLE causes several windows to open, so you will probably want a separate desktop for your browser.)
VPython programs are true python programs in the sense that you can write comments, make assignments to variables, define functions, and so on. However, it is better to think of a VPython program as a scene. To create objects in your scene, you will need to use the predefined objects and functions that are included in the "visual" module which is part of VPython. To do this you will need to "import" the module. However, the import command you will use is slightly different from the "import random" command you used for previous programs. The very first line in any VPython program/scene (after the comments, which are still required in VPython programs) should be:
from visual import *(The from ... import ... python command has a slightly different effect from the import ... command. The different effects are not important here, just realize that this is how you will gain access to the various graphics object in VPython. You will still possibly have need to import random for some of your scenes, but not just yet.)
VPython is designed to do 3D graphics. However, by just ignoring the z-axis, you can draw some rudimentary 2D figures. When you run a VPython program, it uses two windows to display the program. Textual information about your running "scene" is shown in the python shell window. Any print statements you may write will output to that window. The other window is the scene "Display" window. That window is where your graphical objects will be displayed. The center of the "Display" window is similar to an X-Turtle window. That is, it's center is the coordinates (0,0). (In reality, it's (0,0,0) for 3D, but you have to think "out-of-the-screen" in that case.) However the display does not have a set size like X-Turtle. That is, you are not limited to a 10x10 area. The display will scale itself to fit in all of your objects, regardless of what coordinates you use. Let's see how this works. Type in the following VPython scene:
from visual import * square = curve(pos=[(0,0),(0,20),(20,20),(20,0),(0,0)])A little explanation. One of the objects in the visual module is the curve object. Now to mathematicians, any line is a curve. So the curve object is just a way to draw lines. The pos is one of the attributes of the curve object (standing for "position"). In this case, the pos attribute specifies a list of ordered pairs. The curve object just connects the dots. All objects in VPython have several attributes that you can set. Most have default values that will be used. (For most objects, the default pos attribute is (0,0,0), but for a curve object, a single point wouldn't be very interesting to look at.)
To display the simple scene above, select the "Run Module" item from the "Run" menu (remember to save your program first - any name with a .py extension will do for now). When you run your program, you will notice activity in the two windows mentioned above. The display window should open and you should see a nice white square on a black background. Notice that you had to specify 5 ordered pairs to cause the square to be drawn. The curve object connects the dots, remember? If you change the dimensions of your square, the object will look the same, because the "Display" window scales itself appropriately. (Try a 1000x1000 square to verify this if you want. You can just change the 20's to 1000's in the code you've already typed.)
Now a white square on a black background is pretty boring. So add some color. First you can add a color attribute to the curve.
square = curve(pos=[(0,0),(0,20),(20,20),(20,0),(0,0)], color=color.red)Notice that additional attributes are added within the parenthesis of the object and are comma-separated from other attributes. The color attribute (the "color" on the left of the = ) must be assigned a value from the color object (the "color" on the right of the = ) . [This may seem a little confusing - just realize that most things in python are "objects" and objects can have various things assciated with them that are accessed by the dot "." notation - sort of like random.choice().] The color object has several predefined colors that are accessed by color.red, color.green, color.cyan, etc..
You can also change the background color of the display window. The default scene display window is named, oddly enough "scene". To change the color, add the following to your program:
scene.background=color.yellowLeave your final scene from above displayed as we move on...
As I said above, VPython is really a 3D rendering language. In the above experiments, we just ignored the z-axis. In reality, when you write an ordered pair for a curve object, it just interprets the third z-coordinate as a zero. Now the curve object is the only object that can be specified this way, and you can't mix both ordered pairs and ordered triples in the same object. But if you don't believe me that there really is a third dimension to the square you created above, try this. Hold your right mouse button down in the display window and move your mouse. You can also zoom in and out by holding down the middle mouse button. These mouse actions are automatically available in any scene you create.
So lets look at some real 3D objects that are available in VPython. The first is the sphere object. Try this command:
ball=sphere(pos=(2,-4,0), radius=5, color=color.green)Use the right-mouse rotation method to see what happens. Notice that the rotation is about the axes of the 3D scene. not the center of the object. What you are actually moving is the position of the "camera" around the 3D scene. The attributes that you specified have default values of you decide to leave out any. Notice that the pos attribute references the center of the sphere.
One other thing to notice here. In both this example and the square example above, we used a name (a varible actually) to hold a reference to the object - in this case "ball". The scene would display exactly the same if you left out the "ball=" (try it). The reason we give names is that it gives us an easy way to change the attributes using the dot "." notation. For example, leaving the code you just wrote, add the line:
ball.pos=(-4,3,-10)
Notice that there is still only one ball, but it looks smaller. You didn't change the radius. Can you explain what happened? You can change other attributes like this as well. Changing the position of an object this way isn't really very interesting, since I could have just set the pos attribute this way in the first place. However, next week when we start animating our scenes, this will come into play in a big way. In this same scene add the following:
ball2=sphere() ball2.pos=(0,2,4) ball2.radius=10 ball2.color=(0,0,1)This is an example of another way to specify attributes. Now run the scene. Use your mouse to make sure you see everything. You could have written "ball2.color=color.blue" in the above and had the same result. The ordered triple for color is just another way to specify color. The triple represents the (red, green, blue) components of a color. A 1 means "all" of that color. You could have said "ball2.color=(0.5,0,0.5)" to get a nice purple color.
Now spheres aren't real interesting either, because it's often hard to tell what side of a sphere you are looking at. Other objects that are available are the box object, the cylinder object, the cone object, and the ring object. They all have several attributes (some of which mean different things depending on the object - the pos attribute for example means something different for a cylinder than it does for a sphere or a box). Check out the online documentation for these 5 objects (sphere, box, cylinder, cone, and ring) at VPython docs. No, really. Check it out now and play around with the objects a little bit before moving on to the exercises. (Note, you will be able to use some of this "playing around" for your 2nd exercise - if you save your work.)
Here are the exercises that you should do for this week's lab report. You should do all three of them. Be sure and test your programs (scenes) thoroughly. And follow the rules of style including meaningful variable (object) names and comments. Don't forget to include your name in the beginning comments of your program. Use a2ps under Linux to print out your programs and hand in. And make sure your "scenes" (programs) are available in your cs120/lab11 subdirectory The report is due at the beginning of class next Monday, April 25.
Exercise 1: Write a VPython scene using only the curve object to do the following. First of all, represent the three axes of the x,y,z 3D space. Make each axis a different color. Since each axis is a line, you only need specify the endpoints of the axis in the pos attribute. (Note: for the z-axis at least, you will need to use ordered triples for the coordinates. You can use ordered triples for the others as well if you want.) Next, in the same scene, create a "wireframe" cube such that no vertex of the cube is on an axis (and the entire cube is within the xyz space that you create). All of the points for this curve object will need to be ordered triples. Be careful how you order your points. Remember: "connect-the-dots". (It's OK to draw over lines more than once.) Use the mouse rotation mode to check your work. Save your scene as wirebox.py.
Exercise 2: Write a single VPython scene that has several (more than 3) different objects of different sizes, shapes, colors, and other attributes. Try to separate the objects in space (ie, don't have any overlapping or touching each other). The purpose of this exercise is to show me that you checked out the online documentation and experimented with several of the objects.
Exercise 3: Write a VPython scene that represents some realistic scene. Like a house and trees, or a table and chair, etc. You must use at least 3 different vpython objects in your scene. Some of your "realistic" objects may be made up of more than 1 vpython object, and although these will necessarily be abstract, I should be able to "recognize" what you are trying to represent. We haven't talked about animation yet, so don't try to do any for this exercise. However, you will be asked to do an animation next week, so keep that in mind. You might be able to build on this exercise for an animation. Some ideas along this line are: a car, a train, a ferris wheel, etc. In any case, some of the points on this exercise will be awarded based on creativity and complexity. Take some time and have fun with it.
Note: Feel free to look ahead at some of the other online documentation mentioned above if you want to, but don't get too carried away for this lab. All that is required here is some creativity and the use of the objects specified above. (And you do have other classes, right?)