Points, Lines, and Shapes
2.1 Sine and Cosine Curves
Trigonometry is the study of the relationships among the angles and sides of a triangle. In the right triangle shown in Figure 2-1, the sine of angle a is the ratio of BC/AB, and the cosine is the ratio AC/AB (It’s a right triangle because one of the angles is 90 degrees, or a “right angle”).
A a
b
c C B
Figure 2-1: A right triangle
A sine or a cosine can take values between –1 and 1. The progress of sine or cosine values for a changing angle, say in the form of a counter from 0 to 360, is along the path of a curve. So, an interesting feature of sines and cosines is that, when we calculate their value for rotating angles, we get a “circular” behavior.
Consider the following code:
1 for(int i=0; i<500; i++){
2 int x = i;
3 int y = int(50. * sin(PI/180.* i) );
4 point(x, y+50);
5 println(“x = “ + x + “ y = “ + y);
6 }
As a reminder, 180 degrees is equal to PI radians. So, to convert x degrees to r radians, we use the formula x = PI/180*r radians. Since sin() and cos() take for angles radians, we always need to convert degrees (0–360) to radians (0.0 – 3.14159). Conveniently, the Processing language offers a command called radians(), which converts degrees to radians (there is also the opposite com-mand called degrees(), which converts radians to degrees).
In the code preceding, we loop from 0 to 180, and for x we use the counter i. This ensures that we have a linear progress of one pixel in x. Similarly, for y we
get the cosine of the counter i (converted to radians), then exaggerated by 50.0.
Since the result is a double, we cast it into an int to assign it to y:
int x = i;
int y = int(50. * sin(radians( i)) );
Then we draw the result using the point() command. So, as x moves on a linear increment based on the looping counter i (with values 0,1,2,3,4,5, . . . ,499), y moves in the y direction, up and down. Note that we also move the whole scene 100 pixels lower in the y direction to center it on the window (see line 4).
The result is shown in Figure 2-2.
Figure 2-2: The output of a sine representation
So, the result is a set of dots (“.”) starting at (0,100) and then as x goes from 0,1,2,3,4, . . . 500, y produces cosine values. Since we know from trigonometry that a cosine will always be between –1 and 1, we multiply by 50 to make y a value between –50 and 50. Obviously, the resulting numbers place the points along the path of a curve. These numbers are sample values that result from the x and y parameters. The more we decrease the distance between consecutive i values, the more precise the path is. If we want to shorten the curve in the x direction, then we need to do the following adjustment to the x coordinate:
1 for(int i=0; i<5000; i++){
2 int x = i/10;
3 int y = (int)(50. * cos(PI/180.* i) );
4 point(x , y+50);
5 }
The resulting points will be placed along a full circle when i goes from 0 to 360, so, in our case, 5000 will result in 5000 / 360 = 13.8 full circles. We don’t want x to go to 5,000 because the screen is only 400 pixels long and it will be drawn outside of the visible screen. So we divide i by 10, and therefore x will go to only 500, resulting in an image like that shown in Figure 2-3.
Figure 2-3: The output of a cosine representation
If we reverse the values of x and y, as is done in the following code, then we can obtain a rotated curve, as shown in Figure 2-4.
1 for(int i=0; i<5000; i++){
2 int x = (int)(50. * cos(PI/180.* i) );
3 int y = i/10;
4 point(x+50 , y);
5 }
Figure 2-4: Reversing the direction of a cosine representation
Now, if we combine the two, alternating sine and cosine, as in the follow-ing code:
1 for(int i=0; i<5000; i++){
2 int x = (int)(50. * cos(PI/180.* i) );
3 int y = (int)(50. * sin(PI/180.* i) );
4 point(x+50 , y+50);
5 }
this will result in the unexpected (perhaps) output shown in Figure 2-5.
Figure 2-5: The output of the combination of a sine and cosine representation
A circle! We will use this technique later on to rotate objects in the screen, because basically what we are doing here is forcing x and y to move on the perimeter of a circle. Or, to be precise, we force x and y to rotate around a center 13.8 times, since the counter goes from 0 to 5,000. If the counter is going from 0 to 180, as shown here:
1 for(int i=0; i<180; i++){
2 int x = (int)(50. * cos(PI/180.* i) );
3 int y = (int)(50. * sin(PI/180.* i) );
4 point(x+100 , y+100);
5 }
we would have created a half-circle (see Figure 2-6), because i is the number of degrees of the rotation angle.
Figure 2-6: A half-circle
The equations used to construct a circle or portions of it are defined through the following formulas:
x=r*cos(i), y=r*sin(i)
where i is the counter or any parameter that changes in an orderly fashion.
here is i and, consequently, the resulting circle is a parametric one. However, in analytic geometry, the equation for generating a circle is different:
x2 + y2 = r2
Such an equation denotes that for every point on a plane, only the points that satisfy the above equation are part of a circle of radius r and center (0,0). The following code generates such a circle (shown on the left in Figure 2-7):
1 for(int x = -50; x<50; x++) 2 for(int y=-50; y<50; y++) 3 if(x*x + y*y == 25*25) 4 point(x+50,y+50);
Line 3 in the above code can be replaced with the following statement:
3 if(x*x + y*y > 25*25 && x*x + y*y < 26*26)
In this case, a circle is produced by selecting a series of points that fit the preceding two inequalities. This circle has a radius that ranges between 25 and 26 (shown on the right in Figure 2-7).
Figure 2-7: Circles produced through analytical equations
By taking a closer look to the two algorithms (i.e., parametric versus analyti-cal) from a computational efficiency point of view, we may observe the follow-ing: the parametric algorithm involves 360 iterations, whereas the analytical involves 100 * 100 = 10,000 iterations. In addition, the parametric algorithm produces a much more precise set of points. Thus, parametric representation is preferable over the analytical, especially if such representations involve anima-tion. In the next section, we will use parametric equations to produce curves.