Assignment 1: Build Your Virtual City (30 Pts)
Chris Tralie
Due Friday 9/18/2020
Click here to see the art contest results!
Overview / Logistics
The purpose of this individual assignment is to enable you to brush up on your knowledge of methods and how they fit together. It is also an opportunity to practice reading documentation for existing methods to learn how to use them. It will also get you to practice the edit -> run -> edit loop, since you will have to tweak your shapes many times to get a good result.
The specific task in this assignment is to write code to generate 3D worlds. It's much easier if you write methods whose sole job is to draw a particular city object, like a fire hydrant or stop light. Then, you can replicate these objects many times by calling the methods over and over again to create complicated parts of the your world (like city blocks).
Click here to download the skeleton code for this assignment, which you can open with NetBeans. You will be editing HW1_VirtualCities/src/MyScene.java
, and you will be opening the files you create with this code in this 3D engine that I created for the web browser.
Learning Objectives
- Write methods to fit a specification
- Follow documentation to use pre-defined methods
- Use methods together in concert to accomplish a task
- Write a complete program with very little code in the
main
function - Work with 3D coordinates programmatically
What to submit
When you are finished, you should submit MyScene.java
to Canvas, as well as your .json
scene files for both the city scene and your art contest and any animated GIFs you made for your art contest. Please also submit a README with the answers to the following questions
- What title would you like to use for your art contest submissions, and what name/pseudonym you would like to use? (results will be displayed on the class web site).
- Approximately how many hours it took you to finish this assignment (I will not judge you for this at all...I am simply using it to gauge if the assignments are too easy or hard)
- Your overall impression of the assignment. Did you love it, hate it, or were you neutral? One word answers are fine, but if you have any suggestions for the future let me know.
- Any other concerns that you have. For instance, if you have a bug that you were unable to solve but you made progress, write that here. The more you articulate the problem the more partial credit you will receive (fine to leave this blank)
Background: 3D Coordinate Systems
A point in 3D space is represented with 3 coordinates: one in the x-axis, one in the y-axis, and one in the z-axis. There are a few different ways to define such a coordinate system, but we will stick to the OpenGL convention in this class. Below is a sketch of the positive coordinate axes for x, y, and z. A point (a, b, c) can be obtained by creating a rectangular prism with side length a along the x-axis, b along the y-axis, and c along the z-axis. The point then resides on the vertex of the cube furthest from the origin where the three axes meet (the red point).
Background: RGB Colors
In addition to perceiving space in 3 dimensions, humans interestingly also perceive color in 3 dimensions. One basis for color representation is the "RGB" or "Red, Green, Blue" axes. Each axis is represented with 8 bits, so possible values are from 0 (no color) to 255 (full saturation of that color). For instance, rgb(255, 0, 0) is red, and rgb(0, 0, 255) is blue.
The widget below allows you to play around with colors, which you may want to do for the art contest.
Background: 3D Scenes And Shapes
Click here to launch the scene viewer in your browser
In this assignment, you will be creating 3D worlds, also known as "scenes," that can be loaded into an engine I made for my computer graphics class known as ggslac. As in the HTML holidays lab, your Java program will write code that this engine can interpret (though it is JSON code instead of HTML). You don't have to worry writing code strings yourself this time, though. Instead, I have provided a series of high level functions that you can use to draw shapes, and which will automatically convert to code on the backend that you can open in the engine, as shown below.
The full documentation for drawing shapes can be found at this link. Below are a few examples with links to the respective documentation. There are two versions of most methods: one for drawing an "axis-aligned" shape, and one for drawing a rotated version. You'll mostly be using the axis-aligned versions in the tasks.
3D Box
- Click here to view the documentation for drawing an axis-aligned box.
- Click here to view the documentation for drawing a rotated box.
Cylinder
- Click here to view the documentation for drawing an axis-aligned cylinder.
- Click here to view the documentation for drawing a rotated cylinder.
Cone
- Click here to view the documentation for drawing an axis-aligned cone.
- Click here to view the documentation for drawing a rotated cone.
Sphere
- Click here to view the documentation for drawing a sphere.
Ellipsoid
An ellipsoid can be viewed as a stretched out version of a sphere or a 3D generalization of an ellipse.
- Click here to view the documentation for drawing an axis-aligned ellipsoid.
- Click here to view the documentation for drawing a rotated ellipsoid.
Special Mesh
For the art contest, you have a variety of triangle meshes available, including my head ("proftralie") and 400 shapes from the Princeton shape benchmark. Click here to view the documentation for the addSpecialMesh
method. The available shapes are listed below (they are case sensitive and will not show up if you don't get them exactly right, so be careful with spelling!)
Airplane1-Airplane20, Ant1-Ant20, Armadillo1-Armadillo20, Bearing1-Bearing20, Bird1 - Bird20, Bust1-Bust20, Chair1-Chari20, cow, Cup1-Cup20, dinopet, Fish1-Fish20, Fourleg1-Fourleg20, genusthree, genustwo, Glasses1-Glasses20, Hand1-Hand20, hand-simple, homer, Human1-Human20, icosahedron, Mech1-Mech20, Octopus1-Octopus20, Plier1-Plier20, proftralie, StyrofoamHead, Table1-Table20, teapot, Teddy1-Teddy20, triangularPrism, Vase1-Vase20
Here's an example with three of the special meshes. You may need to scale them to get them to the size you want, since they have all been "normalized" to the same scale.Programming Tasks
You will start by making a series of methods that draw specific city objects. Since you'll want to draw many copies of these in different places, you must specify parameters to move the shapes around. For example, if I have a box that's normally centered at (1, 2, 5), I should be able to specify a difference of cx
and cz
to shift it in the X and Z directions, so that the new box would be centered at (1+cx, 2, 5+cz) You don't have to get the exact shapes that are shown in the pictures, but you should get reasonably close. I'll start by giving you a simple example below that draws a street sign.
Example: Sign
We can draw a simple sign with a thin cylinder for its poll and a thin box for the sign itself. Below is an example of how one might accomplish this with a method (this method is provided in the starter code)
Here's an example code snippet that calls this method to create two signs
Tree (5 pts)
Create a method that draws a simple "lollipop" tree, which consists of a brown (rgb 102, 51, 0) trunk of a specified height, and a green (rgb 0, 255, 0) ellipsoid for the "leaves." The height should be a parameter to the method so you can draw trees of varying heights.
Below is an example of an 8 meter tall tree next to a 6 meter tall tree (so calling the method twice).
Fire hydrant (5 pts)
Create a method that draws a red (rgb 255, 0, 0) fire hydrant that is roughly 1 meter tall. The fire hydrant should consist of a small cylinder at its base with a larger, thinner cylinder on top. It should also consist of a sphere on the top of the taller cylinder, and two boxes coming out right below the sphere.
Stop light (5 pts)
Create a method that draws a stop light. The main pole on the left should be 8 meters tall, and the horizontal pole at the top should be 8 meters wide. Attach a box to the horizontal poll that will hold the lights. The top light should be a red (rgb 255, 0, 0) sphere, the middle light should be a yellow (rgb 255, 255, 0) sphere, and the bottom one should be a green (rgb 255, 255, 0) sphere.
Below is an example stoplight with a fire hydrant next to it for scale.
Sedan (5 pts)
Create a method that draws a (very boxy) car, either facing east/west or north/south, with a particular color. It should have one box of that color that is 4.5 meters long, 1.7 meters wide, and 0.7 meters tall. On top of that, it should have a slightly offset box that is 3.5 meters long, 1.4 meters wide, and 0.8 meters tall. On the bottom box, there should be two grey cylinders of radius 0.5 and height 2 to represent the wheels. For the east/west car, you will have to rotate the cylinder around the x-axis by 90 degrees, and for the north/south car, you will have to rotate the cylinder around both the x-axis and the y-axis by 90 degrees.
Below is an example of a red east/west car and a yellow north/south car, with a fire hydrant and stop light for scale (that red car should probably get out of the way...)
City Block (5 Pts)
Create a method that creates a city block by calling the other methods. It should have the following:
- At least two cars
- At least two trees of different heights
- At least one fire hydrant, stop light, and sign
- At least one building (which can simply be a large box)
Finally, setup the method so that it takes an offset, and use it to draw at least two copies of this city block to create an entire city. This is what your drawScene()
method should contain when you submit your MyScene.java
file to canvas.
Style (3 Pts)
You will be graded on adherence to the style guide. Pay particular attention to your method documentation.
Art Contest (2 Pts)
Fill in the drawArtContest()
method to draw anything you want. Unleash your creativity! Your scene does not have to be a city. Please indicate in your submission a title for your scene and what name or pseudonym you would like to use for the contest. The winner will receive 5 points of extra credit.
In addition to the scene, you may also want to submit a movie of it. The GIF below shows how to select two different cameras and automatically fly between them
The result is as follows