Here's an exhaustive trace of the program. I hope this helps. Welcome to programming, by the way!
First, declare some globally accessible variables (variables that can be seen everywhere). This only happens once, before anything else.
Code:// buffer... is this supposed to be 10?
int size = 8;
// Diameter of the shape
int length = 20;
// Height of the shape
int aSize;
// Position of shape
float aPos;
// Speed of the shape
float aSpeed;
// Left (-1) or Right (1)
int aDirection = 1;
Next, set up the environment. This only happens once automatically, before anything is drawn.
Code:void setup() {
// Make the applet window 200px x 200px
size(200, 200);
// Set the desired framerate as 60fps (helps JAVA2D)
framerate(60);
// Place the shape in the middle of the window to start
aPos = width/2;
}
Finally, draw a frame. This happens repeatedly and can be considered your "main" method.
Code:void draw() {
// Refresh the background (essentially paints over the last
// frame). Try removing this line to see what it's doing.
background(102);
// Make my "fill" color white
// Note: this line is redundant since it's white by default
fill(255);
// Calculate the speed of our shape for this frame.
// What's with the parameter? Well, consider that aPos will
// always be between 10 and 190 and watch what happens:
//
// When aPos is 10 the parameter will be 10/192 (almost zero)
// When aPos is 190 the parameter will be 190/192 (almost one)
//
// This means that the parameter is basically acting like a
// percentage
//
// Note, the intended parameter might be:
// (aPos - size) / float(width - size * 2)
//
// What does the hump function do?
// You have to look at the method to find out.
// Here, we're just interested in the fact that it returns _a_
// value.
aSpeed = hump(aPos/float(width-size);
// Calculate a new position based on the speed.
// The method used here is known as "forward Euler integration"
// The process is fairly simple to visualize:
//
// If I'm at position x now, traveling at v velocity,
// where will I be in t seconds?
// answer: x + v * t;
//
// what happens if t is always 1?
// answer: x + v
//
// Notice that x just represents our position in time so we get
// x = x + v (this is sometimes compacted to x += v)
//
// This code needs to turn speed into a velcity
// (we need to add direction to our magnitude)
//
// Looks like Casey also wanted to bump up the speed slightly
// (by 0.5). Perhaps to make sure we always have a minimum
// speed?
//
// Since hump always returns a value between 0 and 1,
// it may be more appropriate to multiply aSpeed to
// scale it instead of offsetting it.
aPos = aPos + ((aSpeed + 0.5) * aDirection);
// Simple collision detection...
// If the shape position exceeds the right border or the left
// border
// (with padding for the radius of the shape)
if (aPos > width - length/2 || aPos < length/2) {
// Change directions
aDirection *= -1;
}
// draw the shape
// Note, the second parameter should _probably_ be height/2
// instead
// The shape is a circle with diameter 20
// The shape is positioned at x: aPos, y: width/2
ellipse(aPos, width/2, length, length);
}
Establish the calculation of the nonlinear motion control, the "hump" function. This method will take a parameter (looks like a percentage from what we saw above) and return a value (looks like a speed from what we saw above).
Code:float hump(float sa) {
// conform our percentage to a specific range of values
// here it will be -1 to 1
sa = (sa - 0.5) * 2;
// Square the result (this means that we get a nonlinear
// relationship)
// These values will also always be positive
sa = sa*sa;
// We should never get a result greater than one,
// but just in case, lets cap the result at one
// (this line isn't needed)
if (sa > 1) { sa = 1; }
// We perform the check above, because we want to find a
// complement
// (we want to move fast through the middle and slow at the
// edges, not slowly through the middle and fast at the edges)
return 1 - sa;
}
Final note:
Why is the nonlinear method called "hump"
Take a look at the speeds produced at the various x positions.