这次作业我针对的主题是“斐波那契螺旋线”
背景知识:斐波那契螺旋线,也称“黄金螺旋”,是根据斐波那契数列画出来的螺旋曲线,自然界中存在许多斐波那契螺旋线的图案,是自然界最完美的经典黄金比例。作图规则是在以斐波那契数为边的正方形拼成的长方形中画一个90度的扇形,连起来的弧线就是斐波那契螺旋线。在这次的作业中,我将用手绘和编程作图两种方式创作斐波那契螺旋线,并试图使之拥有“动态”的效果,还会再斐波那契螺旋线的基础上进行修改,做出意料之外的效果。
首先,我在速写本上画一个斐波那契螺旋线:
根据定义,这个螺旋线是在以斐波那契数为边的正方形拼成的长方形中一个个画出来的曲线构成的,首先我要先打格子作为参考
之后按照规则,我要依次旋转画出边长为1、1、2、3、5、8、13的正方形,我以一个小格子的边长为1
然后在每个正方形中画一个90度的扇形,使之成为螺旋线
这样我手绘的斐波那契螺旋线就画好了,但是因为我没有圆规,所以每个扇形画的都不标准,所以这个斐波那契螺旋线也是不太标准的螺旋线,只能说思路正确、步骤正确,效果还凑合。
下面,我要编程来实现斐波那契螺旋线
思路是这样的:
1、定义一个空的斐波那契数组
var Fibonacci = [];
2、初始化
function setup(){
createCanvas(windowWidth, windowHeight);//画布适应窗口大小
background(127); //背景为灰色
}
3、画螺旋线
首先,我要思考之前文字和公示表达的斐波那契螺旋线的定义,试图在脑海里形成画面,但是这不如我直接画在纸上更直观,于是刚才的手绘派上用场了。
我要先创建一个斐波那契数列,这个实现起来很简单,我只需要得出每一项并放进之前创建的数组里
for( var i = 0; i < 20; i ++){ //20度-90度
var a = i <= 1 ? 1 : Fibonacci[i-1] + Fibonacci[i-2]; //如果i等于0或1,那么a等于1;否则a等于斐波那契数列前两项的和
Fibonacci.push(a); //将得到的每个a加入斐波那契数列中
}
之后开始画弧形,之前手绘的时候,我在每个正方形里画了四分之一的圆弧,也就是说,每个弧的直径是2*a,圆心一开始设置为(0,0)更方便,但是我之前要先调整坐标系,因为默认的坐标系原点是在左上角
调整坐标系:
translate(windowWidth/2, windowHeight/2);//调整坐标系
画下一个圆的时候,圆心的位置都会变化,而且是有角度的变化,在循环当中,我想始终用同一个画弧形的参数的话,调整坐标系更方便,也就是说,每次画完一个弧,坐标系要顺时针旋转90度,沿X轴反方向移动斐波那契数列前一项的长度。
for( var i = 0; i < 20; i ++){ //20度-90度
var a = i <= 1 ? 1 : Fibonacci[i-1] + Fibonacci[i-2]; //如果i等于0或1,那么a等于1;否则a等于斐波那契数列前两项的和
Fibonacci.push(a); //将得到的每个a加入斐波那契数列中
arc(0,0,a * 2,a * 2,0,PI / 2); //绘制圆心在(0,0),直径为2*a度数为90度的弧形
rotate(PI / 2); //将坐标系按顺时针旋转90度
translate(-Fibonacci[i-1],0); //将坐标系沿着X轴反方向移动数列上一项的长度
}
在加上绘制前参数的设置,就能绘制一个斐波那契螺旋线了:
现在我想加上动态的效果
看这个螺旋线的时候,其实本身就有一点点“旋转”的感觉,那如果我让他真正的旋转起来呢
加两段代码:
frameRate(10);
rotate(-PI / 50 * frameCount);
效果是这样的:
下面我试图让画面变得更生动些:
以上两幅图我如何用手绘的方式表达呢?‘
大概是这样,螺旋线的话,至少还能有一点动态的感觉,但换成三角形或者是填充的图形,我就没办法画出动态的效果了。
总结:在上次实验中,我简单随意的画了一个静态的机器人,随后用编程的方式画出来了。那个时候我的感受是,手绘和码绘简直天壤之别,因为手绘是一个随意的过程,而编程是一个严谨的过程。我觉得这个只是从一个过程得出的结论,并不具有说服力,所以我这次实验找了一个比较严谨,具有逻辑性的绘画主题——斐波那契螺旋线。
在手绘过程中,我需要严谨的思考,将抽象的数学概念转化为形象的画面表现出来,并且要严格遵循规则。打格子,画边长为多少的正方形,如何旋转角度,画弧线......整个过程下来与之前的机器人完全不同,因为这次不能随意发挥了。
在编程实现的过程中,我发现,编程的时候我要考虑的问题,已经在刚刚手绘过程中得到了思考,画面感已经有了,逻辑也理顺了,我要考虑的问题,仅仅是我的绘画逻辑如何用代码实现。我发现,之前手绘过程大大降低了我编程的逻辑难度。
之后,我要添加“动态效果”,首先这个螺旋线本身是具有一点点“旋转”的视觉效果的,但是我想让它真正旋转起来的话,在速写纸上以我的水平是很难实现的,我只能用漫画的手法在旁边加上两条线,但效果并不好。但是在代码里,我只需要加上两行,它就转起来了。我又调整了其他的代码,比如说,将弧形改为三角形或者矩形,或者直接让每一次的旋转过程留在页面上,制造“螺旋线填充”的效果,这些在代码里都是很容易做到的事情,并且效果也是非常棒的,但是在我的速写本子上我一筹莫展。
所以说,对于“运动”或者说“动态效果“的实现,没有美术功底的人是很难直接通过手绘的方式表现出来了,静态画面中表达的”动态“,通常需要人脑的联想,它并没有很直观,而编程能非常直观的让画面动起来,非常直接和高效。
如果让我完成一幅动态的作品,我会毫不犹豫的选择编程实现。