По сути, это то, что он делает вертикальную косинусную кривую с изменяющейся амплитудой. Вот ссылка на нечто похожее на то, что делает программа. https://www.desmos.com/calculator/p9lwmvknkh
Вот объяснение этих различных частей по порядку. Я собираюсь сослаться на некоторые переменные из ссылки, которую я предоставил:
float offset = frameCount * 0.01
Что это делает, это определяет, насколько быстро анимируется кривая косинуса. Это «а» значение из десмоса. Чтобы запустить программу, каждый эллипс должен немного изменить свой угол в функции косинуса, чтобы он перемещался. frameCount
- это переменная, в которой хранится текущее количество кадров, для которых выполняется анимация / эскиз, и она увеличивается в каждом кадре, подобно анимируемому значению a.
for (int i = 1; i <= circlenumber; ++i) {
float angle = i*19 + offset;
Это здесь отвечает за определение того, как далеко от вершины должен быть текущий эллипс, измененный с помощью коэффициента растяжения. Он увеличивается каждый раз, так что каждый эллипс немного дальше вдоль кривой косинуса. Это эквивалентно 5 (у + а) из десмоса. Значение y - это i, поскольку оно является зависимой переменной. Это так, потому что для каждого эллипса нам нужно определить, как далеко он находится от вершины, а затем как далеко от центра. Смещение является значением a по причинам, рассмотренным выше.
float x = width/2 + cos(angle) * amplitude
Это вычисляет, как далеко эллипс находится от центра экрана (x-center, значение y определяется для каждого эллипса, по которому это эллипс) Ширина / 2 просто перемещает все эллипсы вокруг центральной линии. Если вы заметили на Desmos, центральная линия - это ось Y. Поскольку в процессе обработки, если что-то выходит за пределы экрана (ниже 0 или выше width
), мы на самом деле этого не видим, в учебном пособии сказано, что это должно быть смещено, так что все это показывает. Амплитуда cos (angle) * по сути является целой функцией Desmos. cos (угол) - это косинус, а амплитуда - это материал до этого. То, что это может быть обработано как, по сути, просто масштабированная версия зависимой переменной. На десмосе я делаю sqrt(-y+4)
, а учебник по сути сделал sqrt(25*i)
. В каждом кадре общая сумма (площадь) сбрасывается до 0. Каждый раз, когда мы рисуем круг, мы увеличиваем его на pi * r ^ 2 (площадь круга). Вот где появляется зависимая переменная (i). Если вы заметили, они пишут float amplitude = sqrt( total / PI );
, поэтому число «пи» из области исключается.
Следует помнить, что круги не являются на самом деле двигаться вниз, это все иллюзия. Чтобы продемонстрировать это, вот некоторый модифицированный код, который будет рисовать линии. Если вы отследите круг вдоль линии, вы заметите, что он на самом деле не двигается вниз.
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
}
}
Надеюсь, это поможет прояснить некоторые проблемы с пониманием.