Geração e Atualização da Animação
// Inside the create_data() function
int points_size = index;
for (int frame = 0; frame < frames; ++frame) {
for (index = 0; index < points_size; ++index) {
// The position of the calculated point is increased and the coordinates are updated
double x = points[index].x, y = points[index].y;
double distance = sqrt(pow(x, 2) + pow(y, 2));
double distance_increase = -0.0009 * distance * distance + 0.35714 * distance + 5;
double x_increase = distance_increase * x / distance / frames;
double y_increase = distance_increase * y / distance / frames;
points[index].x += x_increase;
points[index].y += y_increase;
// Draw points using XSetForeground and XFillArc
XSetForeground(display, gc, points[index].color);
XFillArc(display, win, gc, screen_x(points[index].x), screen_y(points[index].y), 2, 2, 0, 360 * 64);
}
for (double size = 17; size < 23; size += 0.3) {
for (index = 0; index < quantity; ++index) {
// Randomly generate the coordinates and color of the point according to the condition, and draw the point using XSetForeground and XFillArc
if ((create_random(0, 100) / 100.0 > 0.6 && size >= 20) || (size < 20 && (double)create_random(0, 100) / 100.0 > 0.95)) {
double x, y;
if (size >= 20) {
x = origin_points[index].x * size + create_random(-frame * frame / 5 - 15, frame * frame / 5 + 15);
y = origin_points[index].y * size + create_random(-frame * frame / 5 - 15, frame * frame / 5 + 15);
} else {
x = origin_points[index].x * size + create_random(-5, 5);
y = origin_points[index].y * size + create_random(-5, 5);
}
XSetForeground(display, gc, colors[create_random(0, 6)]);
XFillArc(display, win, gc, screen_x(x), screen_y(y), 2, 2, 0, 360 * 64);
}
}
}
}
-
points_size é usado para obter o número de pontos no quadro de animação atual, calculado a partir da seção de código anterior. index é o número de pontos gerados anteriormente.
-
O loop externo for (int frame = 0; frame < frames; ++frame) é usado para iterar sobre cada quadro da animação, e frames especifica quantos quadros existem no total.
-
O loop interno for (index = 0; index < points_size; ++index) é usado para processar cada ponto no quadro atual. Em cada quadro, ele faz o seguinte:
- Primeiro, calcula a nova posição de cada ponto. Isso é feito pela seguinte fórmula:
double x = points[index].x, y = points[index].y;
double distance = sqrt(pow(x, 2) + pow(y, 2));
double distance_increase = -0.0009 * distance * distance + 0.35714 * distance + 5;
double x_increase = distance_increase * x / distance / frames;
double y_increase = distance_increase * y / distance / frames;
points[index].x += x_increase;
points[index].y += y_increase;
Esses cálculos são usados para atualizar as coordenadas x e y do ponto para alcançar o movimento do ponto na animação. distance_increase controla a velocidade com que o ponto se move, que varia com a distância da posição original do ponto.
- Desenha pontos usando as funções
XSetForeground e XFillArc. Isso desenha o ponto na tela, XSetForeground para definir a cor da pintura, XFillArc para desenhar um ponto preenchido, e as coordenadas do centro do círculo são convertidas pelas funções screen_x e screen_y.
- A segunda parte do loop interno
for (double size = 17; size < 23; size += 0.3) é usada para gerar pontos adicionais no quadro atual. Neste loop, cada ponto é gerado, colorido e desenhado na tela.
- As coordenadas e cores dos novos pontos são geradas aleatoriamente de acordo com as seguintes condições:
Se size >= 20 e o número aleatório for maior que 0.6, ou size < 20 e o número aleatório for maior que 0.95, um novo ponto é gerado.
- As coordenadas x e y dos pontos gerados são calculadas a partir da posição do ponto original e alguns deslocamentos aleatórios.
double x, y;
if (size >= 20) {
x = origin_points[index].x * size + create_random(-frame * frame / 5 - 15, frame * frame / 5 + 15);
y = origin_points[index].y * size + create_random(-frame * frame / 5 - 15, frame * frame / 5 + 15);
} else {
x = origin_points[index].x * size + create_random(-5, 5);
y = origin_points[index].y * size + create_random(-5, 5);
}
- Finalmente, use as funções
XSetForeground e XFillArc para desenhar o ponto gerado na tela, assim como o ponto anterior.