Step 3: Constants and Trigonometry

In this step you'll learn about constants and some math functions. Add the following code right before the closing brace of the ClockApplet class:

//
// Helper functions
//

// Conversion constant
private final double deg2rad = Math.PI / 180;

// Returns a point at the given angle and radius from the center
private Point getArcPoint(double tick, double radius) {
	double angle = (90 - tick * 6) * deg2rad;
	double x = halfSize + radius * Math.cos(angle);
	double y = halfSize - radius * Math.sin(angle);
	return new Point((int)x, (int)y);
}

Constants

We first define a constant—a value that is never changed in the program—by using the final modifier. Here is the syntax for defining a constant:

[access-modifier] final data-type identifier = value;

You can use constants to make your code more readable, and also more easy to maintain. For example, the deg2rad constant here is used to convert from degrees to radians:

private final double deg2rad = Math.PI / 180;

The formula in question is radians = degrees * (PI / 180). Whenever we need to convert a value to radians, we can multiply the value by deg2rad instead of (PI / 180). It's clearer, and it also saves us one division operation, since constants are evaluated at compile time. Note that Math.PI is a constant too, defined as 3.14159265358979323846 according to the documentation. The Color.black value that we've been using is—you guessed it—also a constant. It's certainly clearer than Color(0, 0, 0)!

getArcPoint in Detail

Let's examine the new getArcPoint() helper function. This method uses some trigonometry to return the Point at the given "clock angle" and radius from the center. "Clock angle" is defined so that 0 is 12 o'clock (straight up), 15 is 3 o'clock (to the right), 30 is 6 o'clock (straight down), etc., basically equivalent to the minute hand. The radius parameter determines the distance the point is to be from the center of the clock: halfSize puts the point right at the edge, halfSize / 2 puts it halfway to the edge, and so on.

I won't go into the details of the math, but note the Math.sin() and Math.cos() functions. These return the sine and cosine, respectively, of the angle you pass to them. The angle is in radians, which is why I defined the deg2rad constant, and the return values for both functions can range from –1 to 1.

Also, look at the last statement:

return new Point((int)x, (int)y);

Because the Point object only works with integers, but x and y are floating-point numbers, we need to cast them to integers by using (int). Casting converts between data types, and Java requires us to explicitly code it when the value loses significant digits. (Converting from double to int truncates the fractional portion.)

In the next step we'll finally complete the createFace() method.


1