运动的圆和静止的螺线 · 重制版
这是一篇旧文,其中的内容可能已经过时。
See the Pen Dynamic Circles, Static Spiral by HandsomeOne ( @handsomeone) on CodePen.
原 Processing 代码丑,勿作参考
这是仿照 Bees & Bombs 的风格制作的动画。
/*
Helldweller 同学告诉我, 一个完整的程序应包含 1/3 的代码和 2/3 的注释. 所以
这次我不嫌啰嗦, 尽管代码很短,还是尽量把每一行的意思说得明白, 以免日后看不懂.
*/
// a 控制螺线的形状, l 控制“圆环”的宽度; s 是圆的直径与圆心范数之比, 由 a 和 l 共同决定.
float a, l, s;
void setup() {
// 画布大小 500*500, 不描边, 帧率 30.
size(500, 500);
noStroke();
frameRate(30);
a = 1/PI;
l = -.5;
// 为保证相邻两圆相切, 圆的直径与圆心范数之比须等于这个数, 在纸上画画就明白了.
s = 2 * dist(1, 0, pow(2, a*l) * cos(l), pow(2, a*l) * sin(l)) / (1 - pow(2, a*l));
}
void draw(){
// 局部变量 c 控制了圆盘的颜色.
int c = 0;
// x 控制了动画中的每一帧, 从 1 慢->快->慢地变为 -0.99, 再变回 1.
float x = cos(frameCount%60 * PI/60.0);
// l*x 意为起始位置与第 0 帧的偏移.
for (float i = 22 + l*x; i > -15 + l*x; i += l) {
// 必须先画大圆, 再画小圆, 所以 i 是由大到小.
// fill(255) -> fill(0) -> fill(255) -> ...
fill((c += 255) % 510);
// 画圆. 圆心共处一等角螺线, 直径的选取使得相邻两圆相切.
ellipse(
pow(2, a*i) * cos(i) + width/2,
pow(2, a*i) * sin(i) + height/2,
s * pow(2, a*i),
s * pow(2, a*i));
}
// if(frameCount <= 30){
// saveFrame("frames/###.gif");
// }
// 将每一帧保存下来以制作动画.
}
制作动画的方法:使用 ImageMagick,在命令行中运行
convert -delay 3 -loop 0 <path/to>/*.gif animation.gif