Homework 28: Moving Squares
Remember to place the 28_movingSquares folder inside your toolkit, next to the other assignments.
Concepts
Focus on one main concept for this assignment: how to use a sine function to model motion that oscillates back and forth.
Using sine to Model Oscillating Motion
Consider a function that you likely take for granted: sine. You may know it in a trigonometric context, where sine gives you the ratio between two sides of a triangle given a particular angle. But consider the numbers that sine generates:
Attribution: wikipedia
What happens to the value of "y" (labeled as f(x) on the vertical axis above) as "x" increases indefinitely? The value returned by sine "oscillates" between 1 and -1 over and over again. This behavior is useful for modeling all sorts of wavelike phenomena.
In particular, this behavior is also useful for modeling the motion of an object that oscillates back and forth. In this assignment, you will use the sine function to modify the vertical position of a simple Square. When implemented correctly, you'll witness an animation of your Square object, in which it moves up and down smoothly, oscillating back and forth.
Instructions
This is a challenge!
Implement a program that draws a row of colored squares on the screen in which the squares "bounce" up and down. While the actual drawing work has been implemented for you, there is one critical component missing: a Square class that meets certain requirements in order for the application to work.
As such, your goal is to implement the Square class given the specifications below. In addition, a test suite is provided to help guide your implementation and ensure that your Square will work with the graphics-generating code.
Your goal is to implement a Square
class that meets these requirements:
- It should have a default constructor. The constructor will not be used, and for this assignment, should not "do" anything and consist of an empty body. Because we are defining a parameterized constructor (below), we must implement a default constructor to satisfy the C++ compiler. In general, default constructors assign default values to member variables. We're telling you that it doesn't have to do anything merely to save you a little time (despite the strange convention).
- It should have the following private member variables:
int sideLength
which represents the length of one side of the square.int red
which will store the "red" RGB valueint green
which will store the "green" RGB valueint blue
which will store the "blue" RGB valueint x
which will store the horizontal positionint y
which will store the vertical positionint initialVerticalPosition
which will represent the "middle" vertical position as the Square oscillates up and down. For example, when theinitialVerticalPosition
is 250, the Square will oscillate with a vertical "y" position above and below 250 (eg, values 150 to 350).
- It should have a parameterized constructor that:
- Accepts six int parameters, in this order:
int length
which should be assigned to the Square'ssideLength
int r
which should be assigned to the Square'sred
attributeint g
which should be assigned to the Square'sgreen
attributeint b
which should be assigned to the Square'sblue
attributeint initX
which should be assigned to the Square'sx
attributeint initY
which should be assigned to the Square'sy
attribute and the Square'sinitialVerticalPosition
attribute
- Accepts six int parameters, in this order:
- It should have the following "getter" accessor methods:
int getRed()
which returns the value of thered
attributeint getGreen()
which returns the value of thegreen
attributeint getBlue()
which returns the value of theblue
attributeint getX()
which returns the value of thex
attributeint getY()
which returns the value of they
attributeint getSideLength()
which returns the value of thesideLength
attributeint getInitialVerticalPosition()
which returns the value of theinitialVerticalPosition
attribute
- It should have a
move
function that is implemented as follows:
void Square::move(double angle) {
y = 34 * sin(angle) + initialVerticalPosition;
}
This function will be called in testApp.cpp, and will be passed a value,
angle
, that continually increases. Note that asangle
continually increases, the Square'sy
attribute will be oscillating with a value +/-initialVerticalPosition
.You should be asking, what is
34
doing there? Sincesin(angle)
returns a value between -1 and 1, we're multiplying that return value by34
to get numbers between 34 and -34. But, why 34? We found this amount of change results in a "nice" amount of motion and is arbitrary.
Note that a test suite also runs, which is called in main
and generates output to the console. If you meet the requirements above and pass the test suite, your program will compile and run, and squares should move up and down on the screen!
How It Works (Reading Code!)
We've implemented the graphics work to keep you focused on classes, but take a look at main
to see how the program works. First it runs your test suite, then it instantiates an ofAppGlutWindow
(a window for 3d graphics). It then starts your OpenFrameworks app in testApp.cpp.
Take a look at testApp.cpp and what setup()
, update()
and draw()
do. Remember, when your OpenFrameworks application starts, it calls setup()
once, and then calls draw()
over and over again. Note that it also calls update()
, before each call to draw()
. The update()
function is where "work" is done before draw()
ing things.
setup()
calls generateSquares()
. Take a look at the function! It opens up a data file containing RGB color values, and uses those values to instantiate some number of squares and "stores" them in a vector called squares
.
update()
updates the "movement amount," which is really the angle value that will be passed to the Square's move()
member function. We chose to increment this slowly, at a rate of 0.1. Since update()
is being called over and over again automatically by OpenFrameworks, it updates the global variable angle
(at the top of testApp.cpp). This is the horizontal "x" value ultimately given to sine
, as shown in the graph near the top of this page.
update()
then moves all the squares in the squares
vector. Notice the "method chaining" in the for
loop of moveSquares()
. Read it from left to right. What is squares
? It's a vector of Square
objects. What is squares.at(i)
? It's a square. Wow! The multiple dots there is a chain of methods, as if telling the computer, "Give me one Square in the vector and call move(angle)
on it."
Lastly, draw()
just draws the squares. See the drawSquares()
function to see more examples of method chaining and how each Square's attributes are used to set the color, size and position of the graphics.
Hints
Start with the required specifications above first. Try implementing the Square class according to the requirements above, and then rely on the test suite.
The console window will display the output of the test suite (eg, "PASSED" or "FAILED").
The code in test.cpp
(and testApp.cpp) illustrate the expected API that your Square class must support.
Ask questions! While software requirements are written to be as clear and specific as possible, we frequently must ask additional questions when we have trouble interpreting requirements as code.
If you'd like to change the colors of the squares, change the numbers in the file 28_movingSquares\bin\data\colors.cfg.txt
. Take a look at testApp.cpp
's generateSquares()
function to see how it reads data from the file and uses those numbers to instantiate Squares objects of a particular color.
Requirements and Rubric
A friendly message from The Terminator, our grading program
Hello ag *bzzzt* again. I will check for the following:
Your program must not print "FAILED" on the console in order to receive full credit.
You must not modify main.cpp (except adding your name), test.cpp or test.h.
Your class definitions should be in square.h and square.cpp, as provided.
I will *bzzzt* try to break your Square with my tests. Can you *bzzt* defeat me?
This work is worth 190 points.
Requirement | Points | Notes |
---|---|---|
Place your name in the comment header in main.cpp | 5 | |
Correct submission of src directory as a .zip file. | 5 | |
Passes all six tests (30 points each) | 180 |
Concepts Exercised: OOP, classes, unit tests, reading code, graphics, mathematics, animation, specification comprehension
© 2011 Yong Joseph Bakos.