|
Introduction
For a point to be located on an Archemedian spiral it's distance from the center of
the spiral (R) must be the same as some percentage (coeff) of it's rotational angle
(theta) around the center of the spiral ie.
R = coeff * theta
Naively, it might be considered that all a shader has to do is,
- convert the s,t location of the point being shaded to
polar coordinates,
- set a value for coeff,
If the angle of rotation (theta) multiplied by the coeff matches it's radial distance (R)
to within a small margin of error
then colorize the micro-polygon, say black, otherwise set it to a background color.
Figure 1 shows that this naive approach, listing 1, does not work. The spiral terminates
after it's first "turn" - he black line should continue along the full spiral shown in blue.
Figure 1 - woops
Listing 1 - woops.sl
|
surface
woops(color bakcolor = 1;
color pencolor = 0;
float coeff = 0.03;
float tolerance = 0.01)
{
float R, theta;
// Convert the s,t location of the shading point
// to polar coordinates.
float xdiff = s - 0.5, ydiff = t - 0.5;
R = sqrt(xdiff * xdiff + ydiff * ydiff);
theta = atan(ydiff, xdiff); // -PI to PI radians
if(theta < 0.0)
theta += 2 * PI; // 0 to 2PI radians
Oi = Os;
// Check if we are close enough...
if( abs(R - coeff * theta) < tolerance)
Ci = Oi * Cs * pencolor;
else
Ci = Oi * Cs * bakcolor;
}
|
Clearly what the shader fails to take into account is the number of turns or
cyles of the spiral. In other words the rotational angle calculated by the conversion
to polar coordinates only go from 0 to 2PI (0 to 360 degrees) when in fact they should
go from zeor to 2PI * turns, say, 0 to 1080 degrees!
Listing 2 provides the code for a shader that will draw a full spiral. However,
becuase of the simple antialiasing that it uses, the "blur"
parameter may need to be adjusted in order to avoid the rendering artifacts shown
on the right of
figure 2.
|