手绘与码绘的“动态”
在之前的博客中我们对比分析了绘制静态作品时,手绘与码绘在各个方面的相同与差异。那么,在表现“动态"时,两者之间又有什么不同呢,接下来尝试一下用手绘与码绘表现动态
作品对比
第一幅码绘作品很简单,只是将四条圆线从不同的距离出发抵达屏幕底部,并将线与背景的颜色对调,移动屏幕,便产生了线忽左忽右一直往下滑落的感觉
代码如下:
float R;
float y1,y2,y3,y4;
float ys1,ys2,ys3,ys4;
float yss1,yss2,yss3,yss4;
int i,j,p,k;
float z;
int finl,c;
boolean s,ss,sss,_s;
void setup(){
size(500,486);
R=40;z=0;
y1=ys1=yss1=-10;
y2=ys2=yss2=y1-10;
y3=ys3=yss3=y1-25;
y4=ys4=yss4=y1-30;
i=j=p=k=0;
i=1;
finl=30;c=18;
_s=true;
s=false;
ss=false;
sss=false;
}
int f1(int x){
if(x==-2)return 5;
if(x==-1)return 15;
if(x==0)return 10;
if(x==1) return 17;
if(x==2) return 30;
if(x==3) return 10;
if(x==4) return 25;
if(x==5) return 35;
if(x==6) return 35;
if(x==7) return 40;
if(x==8) return 45;
if(x==9) return 45;
if(x==10) return 55;
if(x==11) return 100;
if(x==12) return 60;
if(x==13) return 30;
return 0;
}
void drawT(float x,float y,float hei){
float z1,z2,z3,z4;
z1=0;
z2=10;
z3=20;
z4=30;
noStroke();
rect(x-R,hei,2*R,y-z1);
arc(x,hei+y-z1-1,2*R,2*R,0,PI);
}
void draw(){
background(0,0,0);
noClip();
translate(0,243);
translate(0,-c*z);
z++;
if(c*z>1000) z=0;
clip(0,-486,500,486);
fill(0,150,150);
rect(0,-486,500,486);
fill(253,252,218);
drawT(70,486,-486);
drawT(70+120,486,-486);
drawT(70+240,486,-486);
drawT(70+360,486,-486);
//-------------------------
clip(0,0,500,486);
fill(253,252,218);
rect(0,0,500,486);
fill(0,150,150);
drawT(70,y1-finl,0);
drawT(70+120,y2-finl,0);
drawT(70+240,y3-finl,0);
drawT(70+360,y4-finl,0);
noClip();
if(c*z<486){
y1+=f1(i);
y2+=f1(i-1);
y3+=f1(i-2);
y4+=f1(i-3);
i++;
}else if(c*z>243*3){
y1=-10;
y2=y1-10;
y3=y1-25;
y4=y1-30;
i=1;
}
//-----------------------------
clip(0,486,500,486);
fill(0,150,150);
rect(0,486,500,486);
if(c*z>486){
fill(253,252,218);
drawT(70,ys4-finl,486);
drawT(70+120,ys3-finl,486);
drawT(70+240,ys2-finl,486);
drawT(70+360,ys1-finl,486);
ys1+=f1(j);
ys2+=f1(j-1);
ys3+=f1(j-2);
ys4+=f1(j-3);
j++;
}else{
ys1=-10;
ys2=ys1-10;
ys3=ys1-25;
ys4=ys1-30;
j=1;
}
noClip();
//------------------------------------
clip(0,486*2,500,486);
fill(253,252,218);
rect(0,486*2,500,486);
fill(0,150,150);
drawT(70,yss1-finl,486*2);
drawT(70+120,yss2-finl,486*2);
drawT(70+240,yss3-finl,486*2);
drawT(70+360,yss4-finl,486*2);
if(c*z>1000){
yss1+=f1(p);
yss2+=f1(p-1);
yss3+=f1(p-2);
yss4+=f1(p-3);
i++;
}else{
yss1=-10;
yss2=yss1-10;
yss3=yss1-25;
yss4=yss1-30;
p=1;
}
noClip();
}
看起来很繁复,其实只是将第一段动画重复三次并对调颜色,然后让画框循环移动就能呈现出循环的动态效果了。接下来看手绘作品。画的是运动时的一帧的动画,不断调整四条线的长度,最后合并成动画时就能达到类似的效果了,这需要不断的调整,而码绘的调整就在函数f1中了。
第二幅码绘作品则是在中间绘制了一个转动的摩天轮,周围辅以旋转的点与线制造出眼花缭乱的感觉。
代码如下:
float x, y, r, R, angle,angles;
float x1,y1,x2,y2;
float angle1,angle2;
float r1,r2,d;
void setup(){
size(600, 600);
r = 20; //圆的直径
R = 100; //运动轨迹的半径
x = 0;
angle = 0;
angles=15;
y = height/2;
r1=300;
r2=250;
d=10;
angle1=0;
angle2=0;
}
void dra(float x,float y,float r,float angle){
x = R *cos(angle);
y = R * sin(angle);
line(x,y,0,0);
ellipse(x, y, r, r);
}
void draM(){
pushMatrix();
stroke(0,0,0);
fill(255,255,0);
ellipse(0,0, R, R);
fill(255,0,0);
triangle(0,0,-40,140,40,140);
noFill();
ellipse(0,0, 200, 200);
fill(255,255,255);
for(int i=0;i<9;i++){
dra(x,y,r,angle+i*(2*PI)/9);
}
angles+=1.2;
angle += pow(1.1,-angles)/2;
if(angles>80){
angles=15;
}
popMatrix();
}
void draw(){
background(253, 252, 218);
translate(width/2, height/2);
noFill();
stroke(0,150,160);
fill(0,150,160);
for(int i=0;i<4;i++){
x1=r1*sin(PI*i/4+angle1);
y1=r1*cos(PI*i/4+angle1);
x2=r2*sin(PI*i/4+angle2);
y2=r2*cos(PI*i/4+angle2);
stroke(0,150,160);
line(x1,y1,x2,y2);
noStroke();
ellipse(x1,y1,d,d);
ellipse(x2,y2,d,d);
x1=-x1;x2=-x2;
stroke(0,150,160);
line(x1,y1,x2,y2);
noStroke();
ellipse(x1,y1,d,d);
ellipse(x2,y2,d,d);
x1=-x1;x2=-x2;
y1=-y1;y2=-y2;
stroke(0,150,160);
line(x1,y1,x2,y2);
noStroke();
ellipse(x1,y1,d,d);
ellipse(x2,y2,d,d);
x1=-x1;x2=-x2;
stroke(0,150,160);
line(x1,y1,x2,y2);
noStroke();
ellipse(x1,y1,d,d);
ellipse(x2,y2,d,d);
stroke(1);
}angle1+=0.03;
angle2+=0.06;
draM();
}
外面点与线的旋转是按帧进行的匀速旋转,而中间的摩天轮则是缓动与缓停,后者在手绘时只需确定好关键帧即可完成,而码绘则需要严格的函数控制。
对比分析
技法
从手绘与码绘的效果来看,手绘的技法主要在于对各种图形的绘制,如果没有纯熟的技巧,那么一条简单的直线和一些简单的图形也无法画的完整,甚至会失去美感,就和上面的两张手绘一样。而码绘的技法则注重于代码的编写和参数的取值上,只要代码正确,就能画出规律的简单图形,而参数的调整最终才会实现漂亮的图形。因此要提高手绘重点在于长期的练习以及创意,而码绘的提高则需要对代码不断地深入学习了。两者都需要长时间的钻研,最后绘制的时候也都要按照一定的逻辑与顺序才能完成。
工具
手绘以纸张等媒介通过笔进行绘画,在不同情况选择不同的画布和笔即可。画图时没有太多的约束,只要想好了要画的图形,便可画出来,画出的效果则要看个人的技法了。
而码绘,首先要有一个专门的软件,如这次的两张码绘都是在processing上创作。其次便要通过代码选择画布的大小颜色,抑或是笔的效果颜色。不同的图形则需要不同的函数实现,如果图形太过复杂,便只有用大量的代码组合生成了。
理念
在理念上,手绘一般先是在脑海里构思“要画什么”,然后便要思考“怎么画”,最后进行一步步的尝试完成绘制。一开始可以只有模糊的构思,最后再成型。
而码绘在构思之后,还有“能否实现”这一步骤需要思考。毕竟码绘使得图形趋向标准化的同时,也限制了自由创意的发展,有时候一条随手就能勾勒的曲线在码绘上却是要许多行代码才能画出。只有在脑海里有了完整的想法,才有可能进行实践。
创作体验
在体验上,手绘明显好过码绘。因为码绘在创作过程需要繁杂的计算,动脑多过动手。而手绘却可以在绘画的过程中不断修正自己的想法。虽然都是通过观察画出的作品来调整出新的作品,但码绘的调整明显比手绘的调整复杂的多。
呈现效果
可以看出,在由以规则图形为主的动画中,码绘的效果明显优于手绘的效果。手绘要体现出效果则需要大量的成品构成动画,且绘制的过程中的图形不可能完全和上一张的图形相同,因此便会出现偏差,有失完美性。
载体
手绘的载体在于画布,你可以画的小于画布,但却无法超出画布的范围。而码绘的载体在我看来在于代码本身,码绘中的画布更像是一个相机,只是显示出了你规定的部分,如果码绘超出了画布范围,那部分依然是存在的
局限性
手绘的局限性在于无法画出完美的规则图形,也就是说,就算你画两张同样的画,那这两张也不会一模一样。另外便是当你需要话无数个相同图形时,码绘中一两行代码便可规定的数量,手绘却需要一个一个循规蹈矩去画,这显然是浪费大量时间与精力的。
而码绘的局限性便在于你可自行发挥的地方过少,若想画出不规则的图形,是极为困难的。就算集合大量的代码也很难做,为了一条短短的曲线就可能浪费大量时间实现。
应用
手绘适合在复杂的画作中深入,发挥自身的想象与创意,最终实现精美的画作。
而码绘由于其规则性,可以用于对数学物理等理论知识的图像化,简单画作的创作,图标设计等。