手绘vs码绘(动态)

主题

用手绘和码绘两种方式创作“运动”主题的作品,对比二者在表现“动态”方面的异同。

码绘展示

码绘一
在这里插入图片描述
码绘二
在这里插入图片描述
这里实现了两幅码绘作品,GIF图制作的不好,但也能看出效果。这个的设计不是我的原创,原图来源于图形学课狄兰老师提供的数字媒体艺术的学生做的一些动图,我不知道原作者,他们应该是画出来的,我偷了个懒,把他们的两个作品用代码实现出来。这里附上原图。我实现了第三列的一二两个。
参考素材
参考素材

手绘展示

在这里插入图片描述
做的时候我一直都没明白手绘怎么展示动态,我首先完成的是六边形循环的那个码绘图,之后才突然想到了什么,然后做了正方体,最后才完成手绘,实际上,做完我仍然是用我自己的理解表现的动态,至于对不对我就不清楚了。

代码

float speed=1.732;
float xspeed=1.5;     ///?1.5
float yspeed=3*15*1.732/2/30;

float radius=20;
float rspeed=0.667;

float x1=50,y1=50;
//float x2=50,y2=50+30*1.732;

float x3=95,y3=50+15*1.732;
int n=0;
void setup() {
  size(265,300);
  frameRate(30);
  smooth();
  
  println(rspeed);
}

void draw() {
  background(255);
  int timer=millis();
  
  if(timer<=1000+n)
  {
   
  }
  else if(timer>1000+n&&timer<=2000+n)
  {
    x1+=xspeed;
    radius-=rspeed;
    
    x3-=xspeed;
   // x2+=xspeed;
   // y2-=yspeed;
  }
  else if(timer>2000+n&&timer<=3000+n)
  {
   // y-=speed;
  }
  else if(timer>3000+n&&timer<=4000+n)
  {
   // x-=speed;
   y1+=yspeed;
   
   radius+=rspeed;
   println(radius);
   y3-=yspeed;
  // x2+=xspeed;
  }
  else if(timer>4000+n&&timer<=5000+n)
  {
    
  }
  else if(timer>5000+n&&timer<=6000+n)
  {
    x1-=xspeed;
    x3+=xspeed;
    
    radius-=rspeed;
   // y2+=yspeed;
  }
  else if(timer>6000+n&&timer<=7000+n)
  {
    
  }
  else if(timer>7000+n&&timer<8000+n)
  {
    y1-=yspeed;
    y3+=yspeed;
    
    radius+=rspeed;
    //x2-=xspeed;
  }
  else /*if(timer==8000+n)8*/
  {
    n=n+8000;
  }
  
//  loopdraw(x1,y1);
  back(x3,y3);
  loopdraw(x3,y3,radius);
//  back(x3,y3);
  loopdraw(x1,y1,radius);

}

void back(float x,float y)
{
  fill(26,56,85); //blue
  rect(0,0,300,y+30*1.732+15*1.732);
  
  fill(253,186,95); //yellow
  rect(0,y+30*1.732+15*1.732,300,300);
}

void loopdraw(float x,float y,float r)
{
  for(int j=-1;j<3;j=j+1)
  {
    for(int i=-2;i<10;i=i+2)
    {
      fill(72,192,208); //little blue
      drawSix(x+90*j,y+30*1.732*i,30);
    
      fill(26,56,85);
      drawSix(x+90*j,y+30*1.732*i,r);
    
      fill(253,186,95);
      drawSix(x+90*j,y+30*1.732*i,20-r);
    }
  }
  for(int j=-1;j<3;j=j+1){
  for(int i=-1;i<10;i=i+2)
  {
    fill(224,84,74);
    drawSix(x+90*j,y+30*1.732*i,30);
  
    fill(253,186,95);
    drawSix(x+90*j,y+30*1.732*i,r);
  
    fill(26,56,85);
    drawSix(x+90*j,y+30*1.732*i,20-r);
  }
  }
}
void drawSix(float x,float y,float a)
{
  beginShape();
  vertex(x-a/2,y-a/2*1.732);
  vertex(x+a/2,y-a/2*1.732);
  vertex(x+a,y);
  vertex(x+a/2,y+a/2*1.732);
  vertex(x-a/2,y+a/2*1.732);
  vertex(x-a,y);
  vertex(x-a/2,y-a/2*1.732);
  endShape();
}

码绘二

PVector location;
PVector velocity;
PVector Clocationleft;
PVector Cvelocityleft;
PVector Clocationfront;
PVector Cvelocityfront;
void setup() {
  size(265,300);
  frameRate(30);
  smooth();
  
  location=new PVector(50,250);
  velocity=new PVector(1,-1);
  Clocationleft=new PVector(50-100,250);
  Cvelocityleft=new PVector(1.5,0);
  Clocationfront=new PVector(50+50,250+50*1.732);
  Cvelocityfront=new PVector(-0.5,-1.732*0.5);
}

void draw() {
  background(253,186,95);
  
  location.add(velocity);
  
  Clocationleft.add(velocity);
  Clocationleft.add(Cvelocityleft);
  
  Clocationfront.add(velocity);
  Clocationfront.add(Cvelocityfront);
  
  for(int i=0;i<=0;i++)
  {
    drawbox(location.x+i*50,location.y-i*50,30,Clocationleft.x+i*50*2.5,Clocationleft.y-i*50,Clocationfront.x+i*50*0.5,Clocationfront.y-i*(50+50*0.5*1.732));
  }
}

void drawbox(float x,float y,float a,float x1,float y1,float x2,float y2)
{
  float dx=a/6*0.8;
  float dy=a/6*1.732*0.8;
//  int timer=millis();
  
  if(x1>x+50)
  {
  //front
  fill(224,84,74);
  stroke(224,84,74);
  quad(x+dx,y+dy, x+a-3*dx,y+dy, x+a/2-dx,y+a/2*1.732-dy ,x-a/2+3*dx,y+a/2*1.732-dy);
  
  fill(72,192,208);   
  stroke(72,192,208);
  quad(x+a,y, x+a/2,y+a/2*1.732, x+a/2-dx,y+a/2*1.732-dy, x+a-3*dx,y+dy);
  quad(x+a/2,y+a/2*1.732, x-a/2,y+a/2*1.732,  x-a/2+3*dx,y+a/2*1.732-dy, x+a/2-dx,y+a/2*1.732-dy);
  drawcuboidfront(x2,y2,a);
  fill(72,192,208);   
  stroke(72,192,208);
  quad(x,y, x+a,y, x+a-3*dx,y+dy, x+dx,y+dy);
  quad(x,y, x-a/2,y+a/2*1.732, x-a/2+3*dx,y+a/2*1.732-dy, x+dx,y+dy);
  
  //left
  fill(224,84,74);//red  
  stroke(224,84,74);
  quad(x-a/2,y-a/2*1.732+dy*2, x-dx*2,y, x-a/2,y+a/2*1.732-dy*2, x-a+dx*2,y);
 
  fill(26,56,85); 
  stroke(26,56,85);
  quad(x-a/2,y+a/2*1.732, x-a,y, x-a+dx*2,y,  x-a/2,y+a/2*1.732-dy*2);
  quad(x-a,y, x-a/2,y-a/2*1.732, x-a/2,y-a/2*1.732+dy*2, x-a+dx*2,y); 
  drawcuboidleft(x1,y1,a);
  fill(26,56,85); 
  stroke(26,56,85);
  quad(x-a/2,y-a/2*1.732,x,y,x-dx*2,y,x-a/2,y-a/2*1.732+dy*2);
  quad(x,y, x-a/2,y+a/2*1.732, x-a/2,y+a/2*1.732-dy*2, x-dx*2,y);
  }
  else
  {
  //left
  fill(224,84,74);//red  
  stroke(224,84,74);
  quad(x-a/2,y-a/2*1.732+dy*2, x-dx*2,y, x-a/2,y+a/2*1.732-dy*2, x-a+dx*2,y);
 
  fill(26,56,85); 
  stroke(26,56,85);
  quad(x-a/2,y+a/2*1.732, x-a,y, x-a+dx*2,y,  x-a/2,y+a/2*1.732-dy*2);
  quad(x-a,y, x-a/2,y-a/2*1.732, x-a/2,y-a/2*1.732+dy*2, x-a+dx*2,y); 
  drawcuboidleft(x1,y1,a);
  fill(26,56,85); 
  stroke(26,56,85);
  quad(x-a/2,y-a/2*1.732,x,y,x-dx*2,y,x-a/2,y-a/2*1.732+dy*2);
  quad(x,y, x-a/2,y+a/2*1.732, x-a/2,y+a/2*1.732-dy*2, x-dx*2,y);
  
  //front
  fill(224,84,74);
  stroke(224,84,74);
  quad(x+dx,y+dy, x+a-3*dx,y+dy, x+a/2-dx,y+a/2*1.732-dy ,x-a/2+3*dx,y+a/2*1.732-dy);
  
  fill(72,192,208);   
  stroke(72,192,208);
  quad(x+a,y, x+a/2,y+a/2*1.732, x+a/2-dx,y+a/2*1.732-dy, x+a-3*dx,y+dy);
  quad(x+a/2,y+a/2*1.732, x-a/2,y+a/2*1.732,  x-a/2+3*dx,y+a/2*1.732-dy, x+a/2-dx,y+a/2*1.732-dy);
  drawcuboidfront(x2,y2,a);
  fill(72,192,208);   
  stroke(72,192,208);
  quad(x,y, x+a,y, x+a-3*dx,y+dy, x+dx,y+dy);
  quad(x,y, x-a/2,y+a/2*1.732, x-a/2+3*dx,y+a/2*1.732-dy, x+dx,y+dy);

  }
  
  
  fill(224,84,74); //top
  stroke(224,84,74);
  quad(x-a/2,y-a/2*1.732,x+a/2,y-a/2*1.732,x+a,y,x,y);
  fill(26,56,85); 
  stroke(26,56,85);
  quad(x-a/2+dx*3,y-a/2*1.732+dy,x+a/2-dx,y-a/2*1.732+dy,x+a-dx*3,y-dy,x+dx,y-dy);
  
}

void drawcuboidleft(float x,float y,float a) //left
{
  float dx=a/6*0.8;
  float dy=a/6*1.732*0.8;
  //x=x;
  
  fill(224,84,74);
  stroke(224,84,74);
  quad(x-a/2,y-a/2*1.732+dy*2,x-dx*2,y,x-a/2,y+a/2*1.732-dy*2,x-a+dx*2,y);
  
  fill(72,192,208); 
  stroke(72,192,208);
  quad(x-a/2,y-a/2*1.732+dy*2,x-dx*2,y,x-dx*2+a*2,y,x-a/2+a*2,y-a/2*1.732+dy*2);
  
  fill(26,56,85); 
  stroke(26,56,85);
  quad(x-dx*2,y,x-a/2,y+a/2*1.732-dy*2,x-a/2+a*2,y+a/2*1.732-dy*2,x-dx*2+a*2,y);
  
}

void drawcuboidfront(float x,float y,float a) //front
{
  //x=x+50;
  //y=y+50*1.732;
  float dx=a/6*0.8;
  float dy=a/6*1.732*0.8;

  fill(26,56,85);    //top
  stroke(26,56,85);
  quad(x+dx,y+dy,x+a-3*dx,y+dy, x+a-3*dx+a,y+dy+a*1.732, x+dx+a,y+dy+a*1.732);
  
  
  fill(72,192,208);   //left
  stroke(72,192,208);
  quad(x-a/2+3*dx,y+a/2*1.732-dy, x+dx,y+dy, x+dx+a,y+dy+a*1.732, x-a/2+3*dx+a,y+a/2*1.732-dy+a*1.732);
 
  fill(224,84,74);   //front
  stroke(224,84,74);
  quad(x+dx+a,y+dy+a*1.732, x+a-3*dx+a,y+dy+a*1.732, x+a/2-dx+a,y+a/2*1.732-dy+a*1.732, x-a/2+3*dx+a,y+a/2*1.732-dy+a*1.732);
}

制作过程

这里想要提一下制作过程,我对手绘和码绘的动态表现的理解实际上都是在制作过程中一点点想到的。

首先我开始准备做的时候是很迷惑的。我认真看了老师的各种资料,感觉信息量有点大,这让我有种高中做阅读理解的体会,这其中是有一套逻辑,但我就是理不清。天生对美和艺术不敏感。所以我做的时候没有去想手绘,参考老师的动态码绘(附加的示例程序
https://shimo.im/docs/36GPANmRVx05EF83/ 《“动态”作品编程示例》,)先实现码绘。

其实这里对码绘实现动态就感到不解了,这不就是动画吗?这让我有种作弊的感觉,这样还算一幅画吗?做的时候我在潜意识下忽略了这点,写这篇博客的时候,又梳理了遍思路,忽然意识到这点。这里写下此时的想法,实际上动画与《“动态”作品编程示例》中的案例,可以明显的区分出来,我认为与时间长短无关,在欣赏的时候动态作品仍然是一幅画的感觉,运动的元素是单调的、固定的,变化的是循环、旋转、放大缩小,当然两者的界限并不分明。

我对运动的理解是运动状态的改变,表现出方向或速度的变化,用码绘,可以很轻松地通过条件分支、循环、函数等流程控制方法来变现一些动态变化。但是手绘如何表现呢?做完六边形的码绘,我对手绘毫无头绪,我对手绘表现动态的手法的印象只停留在速度线和残影,而这个六边形实际上无法用这种办法表现,我起初的想法还是类似做动画的方法,突然看到这帧图。
在这里插入图片描述
这是我思考动态的关键,你可能不清楚这张图表现了什么,但我发现我明白这帧图下一帧的状态。这个动图的变化规律其实是挺复杂的,所以我可以通过它的一张静止的状态图明白它的前和后的状态,也就是说在我脑海中它是有过程的,或者说是运动的。

这也是我要实现另一张动图的关键,另一张的规律更简单,更容易让人感受到我的体会。
在这里插入图片描述
这张图是静止的,但很容易让人感受到它的变化趋势。这张图可以理解成一个正方体和两个长方体构成的整体随时间变化的不同运动状态。

在这里插入图片描述
再看这一张,这张没有其他时间这个整体的运动状态,但实际上通过 颜色和两个长方体的位置我们还是能感受到它是运动的。就是说,图中的红蓝深蓝三色和刚好吻合的大小其实揭示了图的运动规律,所以我们可以通过规律脑补出它的运动规律。

现在回到上面的第一张图,从遮盖关系,颜色变化,背景变化上,是可以推测出运动过程的。这张静态图可以体现一部分动态图的变化规律。
在这里插入图片描述

到这其实我对“动态”的表现仍然不清楚,这里的想法是在静态图中能够表现出“过程”。但其实没有看过动图,没有掌握运动规律,第一次看到这张图,是很难感觉到图的运动。

那么残影和速度线呢?这些多用在漫画中,表现浮夸,现实中很少见,但大部分人第一次看漫画还是可以理解。我想起高中一次下完雨,我在操场打篮球,当时清楚的看到篮球飞出去的时候有残影(当时中二的想到篮球火,现在想想那可能是我有散光的征兆),残影和速度线应该是类似的,是视觉残留产生的现象,漫画把速度快的现象简单的抽象成了速度线,而视觉残留是每个人都有的,所以我们都能理解这种表现手法。

那如果每个人都能知道我的动图的变化规律,那这张静态图是不是也可以看出动态了?我做的时候想到这点的时候很兴奋,感觉自己好像发现了新大陆,然而在我不断理顺思路,参考老师的文章,发现我想到的理论和老师文中的内容有类似的地方。

这里要提到《编程的思想来理解绘画—— (一)用”一笔画“表现“过程美”》中说书法比画更容易体现出创作过程的动感,而画则是这样的:

在创作大写意绘画时, 画家的每一笔都要考虑如何与前面的所有笔画进行搭配,作画的过程是一个连贯的思维过程,不能像画油画那样反复堆叠修饰,而是要一气呵成。然而,这些动态散落于画面的各个细部,无法像书法作品那样呈现为一组在时间上衔接呼应的完整过程,这些笔触蕴含的思维过程也就消匿无踪。只有经验丰富的画手,才能从笔触的形态琢磨出前后衔接的顺序,但这已经不符合审美的直观性要求,更不是普通人能做到的了。

那么外国人第一次看草书能不能感受到过程美呢?我查到的大部分看法都是把书法看作画,某种神秘符号,而对大部分中国人来说也是难以欣赏的。不谈美感、意义、文化等,仅仅从形状上来说,书法是有一套规定的写法的,例如永字八法,我对此没有深的研究,只是曾经语文老师教过一些基础,他喜欢用“一”举例,书法上的“一”要有起承转合,并且字是固定的,我们中国人即使不懂书法,也知道字是什么,从哪一笔开始写,所以比较好理解书法的过程美。

为什么要说这点呢?老师提到经验丰富的画手,才能从笔触的形态琢磨出前后衔接的顺序,而书法实际上也是因为我们已经学会了字的写法,我们已经是“经验丰富的写手”,并且书法的基础规则和变化与画相比不大,草书已经难以看出原来字的形状,但仍然是按照从右到左,从上到下的顺序写的,而画的手法要比书法的写法更加自由,也就更难以感受的过程。

到这,实际上我简陋的看法就出来了,仅仅就动态来说,视觉残留,书法,画法这些都是一种规律,而残影,书法和画的过程美,就是基于规律表现出的现象。并且从视觉残留到书法到画法,它们的规律是从简单到复杂的,所以表现出的现象的理解难度也是递增的,残影我们都能理解动态,书法需要一些基本的书法知识,但画过于复杂,已经很难从画中明显的看出时间过程。

而我的手绘静态画,也可以用这个理论来解释,颜色、大小、重叠关系以及时间前后的暗示就是一种规律,基于这个规律来看我的静态画,也就能理解画中物体的运动过程。

总结

做完感受最深的就是理论还是要与实践结合。初读《编程的思想来理解绘画—— (一)用”一笔画“表现“过程美”》,对其中的理论毫无感触,自己做的时候,发现了些问题,思考理论来解释时,再去看文章内的理论,发现我想到的理论能在文中找到许多印证的地方。

我思考的东西实际上是手绘与码绘在呈现效果上的不同,码绘可以通过代码的循环递归条件判断等方法较容易的实现动画,而手绘则需要在静态中体现出过程,然而完成的画作往往都已经丢失了绘画过程信息,所以简单的画更容易体现画的过程,而完整复杂的画已经看不出这些信息。这是绘画本身的过程,而绘画对象的运动过程还是可以通过一些信息暗示出运动过程。

猜你喜欢

转载自blog.csdn.net/qq_38694695/article/details/84255575
今日推荐