运动的圆和静止的螺线 · 重制版
See the Pen Dynamic Circles, Static Spiral by HandsomeOne (@handsomeone) on CodePen.
原 Processing 代码丑,勿作参考
这是仿照 Bees & Bombs 的风格制作的动画。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
/* Helldweller 同学告诉我, 一个完整的程序应包含 1/3 的代码和 2/3 的注释. 所以 这次我不嫌啰嗦, 尽管代码很短,还是尽量把每一行的意思说得明白, 以免日后看不懂. */ float a, l, s; // a 控制螺线的形状, l 控制“圆环”的宽度; s 是圆的直径与圆心范数之比, 由 a // 和 l 共同决定. void setup() { size(500, 500); noStroke(); frameRate(30); // 画布大小 500*500, 不描边, 帧率 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(){ int c = 0; // 局部变量 c 控制了圆盘的颜色. float x = cos(frameCount%60 * PI/60.0); // x 控制了动画中的每一帧, 从 1 慢->快->慢地变为 -0.99, 再变回 1. for (float i = 22 + l*x; i > -15 + l*x; i += l) { // l*x 意为起始位置与第 0 帧的偏移. // 必须先画大圆, 再画小圆, 所以 i 是由大到小. fill((c += 255) % 510); // fill(255) -> fill(0) -> fill(255) -> ... 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,在命令行中运行
1 |
convert -delay 3 -loop 0 path\to\*.gif animation.gif |