I have a Java program written in Processing I made that draws a spiral in processing but I am not sure how some of the lines of code work. I wrote them based on a tutorial. I added comments in capital letters to the lines I do not understand. The comments in lowercase are lines that I do understand. If you understand how those lines work, please explain in very simple terms! Thank you so much.
void setup()
{
size(500,500);
frameRate(15);
}
void draw()
{
background(0); //fills background with black
noStroke(); //gets rid of stroke
int circlenumber = 999;// determines how many circles will be drawn
float radius = 5; //radius of each small circle
float area = (radius) * (radius) * PI; //area of each small circle
float total = 0; //total areas of circles already drawn
float offset = frameCount * 0.01; //HOW DOES IT WORK & WHAT DOES IT DO
for (int i = 1; i <= circlenumber; ++i) { // loops through all of the circles making up the pattern
float angle = i*19 + offset; //HOW DOES IT WORK & WHAT DOES IT DO
total += area; // adds up the areas of all the small circles that have already been drawn
float amplitude = sqrt( total / PI ); //amplitude of trigonometric spiral
float x = width/2 + cos(angle) * amplitude;//HOW DOES IT WORK & WHAT DOES IT DO
float hue = i;//determines circle color based on circle number
fill(hue, 44, 255);//fills circle with that color
ellipse(x, 1*i, radius*2, radius*2); //draws circle
}
}
Essentially what this is doing is doing a vertical cosine curve with a changing amplitude. Here is a link to a similar thing to what the program is doing. https://www.desmos.com/calculator/p9lwmvknkh
Here is an explanation of this different parts in order. I'm gonna reference some of the variables from the link I provided:
float offset = frameCount * 0.01
What this is doing is determining how quickly the cosine curve is animating. It is the "a" value from desmos. To have the program run, each ellipse must change its angle in the cosine function just a little bit each frame so that it moves. frameCount
is a variable that stores the current amount of frames that the animation/sketch has run for, and it goes up every frame, similar to the a-value being animated.
for (int i = 1; i <= circlenumber; ++i) {
float angle = i*19 + offset;
This here is responsible for determining how far from the top the current ellipse should be, modified by a stretching factor. It's increasing each time so that each ellipse is slightly further along in the cosine curve. This is equivalent to the 5(y+a) from desmos. The y-value is the i as it is the dependent variable. That is the case because for each ellipse we need to determine how far it is from the top and then how far it is from the centre. The offset is the a-value because of the reasons discussed above.
float x = width/2 + cos(angle) * amplitude
This calculates how far the ellipse is from the centre of the screen (x-centre, y value is determined for each ellipse by which ellipse it is). The width/2 is simply moving all of the ellipses around the centre line. If you notice on Desmos, the center line is y-axis. Since in Processing, if something goes off screen (either below 0 or above width
), we don't actually see it, the tutorial said to offset it so the whole thing shows. The cos(angle)*amplitude is essentially the whole function on Desmos. cos(angle) is the cosine part, while amplitude is the stuff before that. What this can be treated as is essentially just a scaled version of the dependent variable. On desmos, what I'm doing is sqrt(-y+4)
while the tutorial essentially did sqrt(25*i)
. Every frame, the total (area) is reset to 0. Every time we draw a circle, we increase it by the pi * r^2 (area of circle). That is where the dependent variable (i) comes in. If you notice, they write float amplitude = sqrt( total / PI );
so the pi from the area is cancelled out.
One thing to keep in mind is that the circles aren't actually moving down, it's all an illusion. To demonstrate this, here is some modified code that will draw lines. If you track a circle along the line, you'll notice that it doesn't actually move down.
void setup()
{
size(500,500);
frameRate(15);
}
void draw()
{
background(0); //fills background with black
noStroke(); //gets rid of stroke
int circlenumber = 999;// determines how many circles will be drawn
float radius = 5; //radius of each small circle
float area = (radius) * (radius) * PI; //area of each small circle
float total = 0; //total areas of circles already drawn
float offset = frameCount * 0.01; //HOW DOES IT WORK & WHAT DOES IT DO
for (int i = 1; i <= circlenumber; ++i) { // loops through all of the circles making up the pattern
float angle = i*19 + offset; //HOW DOES IT WORK & WHAT DOES IT DO
total += area; // adds up the areas of all the small circles that have already been drawn
float amplitude = sqrt( total / PI ); //amplitude of trigonometric spiral
float x = width/2 + cos(angle) * amplitude;//HOW DOES IT WORK & WHAT DOES IT DO
float hue = i;//determines circle color based on circle number
fill(hue, 44, 255);//fills circle with that color
stroke(hue,44,255);
if(i%30 == 0)
line(0,i,width,i);
ellipse(x, i, radius*2, radius*2); //draws circle
}
}
Hopefully this helps clarify some of the issues with understanding.