Animation Generation and Update
// 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
is used to get the number of points in the current animation frame, calculated from the previous code section. index
is the number of points previously generated.
-
External loop for (int frame = 0; frame < frames; ++frame)
is used to iterate over each frame of the animation, and the frames
specify how many frames there are in total.
-
Internal loop for (index = 0; index < points_size; ++index)
is used to process each point in the current frame. In each frame, it does the following:
- First, calculate the new position of each point. This is done by the following formula:
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;
These calculations are used to update the x and y coordinates of the point to achieve the motion of the point in the animation. distance_increase
controls the speed at which the point moves, which varies with the distance from the point's original position.
- Draw points using the
XSetForeground
and XFillArc
functions. This draws the point onto the screen, the XSetForeground
for setting the paint color, the XFillArc
for drawing a filled dot, and the coordinates of the center of the circle are converted by the screen_x
and screen_y
functions.
- The second part of the inner loop
for (double size = 17; size < 23; size += 0.3)
is used to generate additional points in the current frame. In this loop, each point is generated, colored, and drawn onto the screen.
- The coordinates and colors of the new points are generated randomly according to the following conditions:
If size >= 20
and the random number is greater than 0.6
, or size < 20
and the random number is greater than 0.95
, a new point is generated.
- The x and y coordinates of the generated points are calculated from the position of the original point and some random offsets.
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);
}
- Finally, use the
XSetForeground
and XFillArc
functions to draw the generated point onto the screen, just like the previous point.