Processing编程自画像

Processing绘制自画像

选色构图

在绘制自画像之前首先需要抽象自己的形象,这里 我将长发作为自己的主要抽象特征。
选用的颜色为暖色系,如下图
在这里插入图片描述
在这里插入图片描述

贝塞尔曲线的使用

在画自画像中多次用到了贝塞尔曲线,这里简单介绍一下用法

用“贝塞尔”工具无论是画直线或是曲线,都非常简单,随手可得。其操作特点是通过用鼠标在面板上放置各个锚点,根据锚点的路径和描绘的先后顺序,产生直线或者是曲线的效果。

我在这里用的是三次贝塞尔曲线:bezier(x1,y1,x2,y2,x3,y3,x4,y4)
点(x1,y1)是曲线的起点,点(x4,y4)是曲线的终点,而(x3,y3)和(x4,y4)是控制曲线走向的点,如下图:

P1和P2是控制点

在processing中,还有一种连续画贝塞尔曲线的方法,例如

   vertex(0,400);
   bezierVertex(width/2-30,330,width/2+50,360,600,410);
   bezierVertex(600,800,600,800,600,800);
   bezierVertex(0,800,0,800,0,800);

这只是把曲线的起点单独取出, bezierVertex的第一个参数就是控制点,最后一个参数是在曲线上的点。

画背景(地面+树)

基础背景比较简单,填色+用贝塞尔曲线画颜色浅一点的地

   beginShape();
   fill(#b6d0c5);
   stroke(#b6d0c5);
   vertex(0,400);
   bezierVertex(width/2-30,330,width/2+50,360,600,410);
   bezierVertex(600,800,600,800,600,800);
   bezierVertex(0,800,0,800,0,800);
   vertex(0,400);
   endShape(CLOSE);

完成后的效果如下:
在这里插入图片描述

考虑到背景比较单调,我们在背景上画一些树,画树的方法参考了这篇博客Processing 基础 | 分形树
简单来说就是用递归的方法来画树,树枝的多少就是递归的出口

void branch(float x, float y, float theta, float len){
//		x,y:树的位置,theta:树的旋转角度,len:树的高度
//		MAX_LEVEL:树的级数,是递归的出口
  if(level > MAX_LEVEL){
    return;
  }
  float toX = x + cos(theta) * len;
  float toY = y + sin(theta) * len;
  // 画主干
  line(x, y, toX, toY); 
  level++; 
  //画左右树枝
  branch(toX, toY, theta + PI / 6, len * 0.8);
  branch(toX, toY, theta - PI / 6, len * 0.8);
  level--;
}

完成以上工作后得到的画面是这样的,效果还不错
在这里插入图片描述

画人物

画脸

画脸用得最多的是ellipse函数
ellipse(x,y,r1,r2)的参数说明
(x,y)是椭圆的位置,r1是椭圆在x轴上的轴,r2是椭圆在y轴上的轴

   //face
  strokeWeight(0.5);
  fill(#f6fdf5);
  stroke(#f6fdf5);
  ellipse(width/2,200,100,110);
  //shy_red
  fill(#fac9b8);
  stroke(#fac9b8);
  ellipse(width/2-30,225,18,18);
  ellipse(width/2+30,225,18,18);
  //mouse
  noFill();
  stroke(#bca497);
  strokeWeight(1);
  bezier(width/2-10, 230, width/2,235,width/2,235, width/2+10, 230);
  //eyes
  fill(#939387);
  stroke(#939387);
  ellipse(width/2-30,200,20,18);
  ellipse(width/2+30,200,20,18);
  //brows
  noFill();
  bezier(width/2-35, 180, width/2-28,179,width/2-28,179, width/2-20, 180);
  bezier(width/2+20, 180, width/2+25,179,width/2+25,179, width/2+35, 180);

效果如下:
在这里插入图片描述

画头发

位于前面的浅色头发

   //hair
  beginShape();
  fill(#959186);
  vertex(width/2-50,170);
  bezierVertex(width/2-30,165,width/2+30,165,width/2+50,170);
  bezierVertex(width/2+45,130,width/2-45,130,width/2-50,170);
  endShape(CLOSE);  
  beginShape();
  vertex(width/2+40,160);
  bezierVertex(width/2+70,165,width/2+70,300,width/2+55,350);
  bezierVertex(width/2+70,300,width/2+60,280,width/2+40,160);
  vertex(width/2-40,160);
  bezierVertex(width/2-70,165,width/2-70,300,width/2-55,350);
  bezierVertex(width/2-70,300,width/2-60,280,width/2-40,160);
  endShape(CLOSE);
  beginShape();
  fill(#f6fdf5);
  stroke(#f6fdf5);
  vertex(width/2+5,170);
  vertex(width/2+10,158);
  vertex(width/2+15,170);
  endShape(CLOSE);

画完如下:
在这里插入图片描述
头发有部分是深色的,位于头部后面,所以深色头发要比脸先画
深色头发代码:

  //hair2
  beginShape();
  fill(#68645b);
  stroke(#68645b);
  vertex(width/2-50,170);
  bezierVertex(width/2-55,180,width/2-60,255,width/2-70,275);
  bezierVertex(width/2-80,299,width/2-75,320,width/2-25,350);
  vertex(width/2+25,350);
  bezierVertex(width/2+75,320,width/2+88,299,width/2+70,275);
  bezierVertex(width/2+65,260,width/2+60,255,width/2+55,180);
  endShape(CLOSE);
  //face

结果如下
在这里插入图片描述

画脖子和裙子

画裙子的时候要注意裙子的线条感,线条不要过于死板。

 //neck
  beginShape();
  fill(#f9fbf6);
  stroke(#f9fbf6);
  vertex(width/2-10,250);
  bezierVertex(width/2-5,260,width/2-8,266,width/2-20,275);
  bezierVertex(width/2-5,285,width/2+5,285,width/2+20,275);
  bezierVertex(width/2+8,266,width/2+5,260,width/2+10,250); 
  endShape(CLOSE);
  
  //skirt
  beginShape();
  fill(#d1bba4);
  stroke(#d1bba4);
  vertex(width/2-20,275);
  bezierVertex(width/2-5,285,width/2+5,285,width/2+20,275);
  bezierVertex(width/2+25,269,width/2+45,285,width/2+50,295); 
  vertex(width/2+30,299);
  bezierVertex(width/2+40,380,width/2+45,400,width/2+80,420);
  bezierVertex(width/2+50,410,width/2+45,410,width/2,420);
  bezierVertex(width/2-25,428,width/2-40,425,width/2-80,410);
  bezierVertex(width/2-50,380,width/2-45,380,width/2-30,299);
  vertex(width/2-50,295);
  bezierVertex(width/2-45,285,width/2-25,269,width/2-20,275); 
  endShape(CLOSE);
  //这里使用画树的方法给小裙子加一个好看的花纹
  fill(#e5cfb8);
  stroke(#e5cfb8);
  strokeWeight(2);
  MAX_LEVEL=4;
  branch(width/2,350, -HALF_PI, 10);
  ellipse(width/2,350,5,5);

在这里插入图片描述

画四肢

画手的代码要放在画裙子之后,画腿的代码放在画裙子之前,这里给手设计的动作是扶着一个斜跨包,所以在画手之前需要画一个斜挎包。
画腿:

  //leg
  beginShape();
  stroke(#f6fdf5);
  fill(#f6fdf5);
  vertex(width/2-25,420);
  bezierVertex(width/2-24,450,width/2-23,480,width/2-30,520);
  bezierVertex(width/2-34,525,width/2-15,540,width/2-10,420);
  endShape(CLOSE);
  
  beginShape();
  stroke(#f6fdf5);
  fill(#f6fdf5);
  vertex(width/2+25,410);
  bezierVertex(width/2+24,450,width/2+23,480,width/2+30,520);
  bezierVertex(width/2+34,525,width/2+15,540,width/2+10,410);
  endShape(CLOSE);
  
  //skirt

画包

 //bag
  beginShape();
  stroke(#5d7c70);
  fill(#5d7c70);
  vertex(width/2-25,272);
  bezierVertex(width/2-20,310,width/2,330,width/2+30,360);
  bezierVertex(width/2+25,365,width/2-24,320,width/2-30,275);
  endShape(CLOSE);
  beginShape();
  stroke(#5d7c70);
  fill(#5d7c70);
  vertex(width/2+30,360);
  bezierVertex(width/2+20,364,width/2+15,368,width/2+34,395);
  bezierVertex(width/2+40,395,width/2+58,395,width/2+65,390);
  bezierVertex(width/2+60,380,width/2+70,360,width/2+30,360);
  endShape(CLOSE);

画手

  
  //arms
  beginShape();
  stroke(#f6fdf5);
  fill(#f6fdf5);
  vertex(width/2-44,297);
  bezierVertex(width/2-52,340,width/2-55,336,width/2+40,380);
  bezierVertex(width/2+42,380,width/2+46,380,width/2+46,374);
  bezierVertex(width/2-42,336,width/2-43,340,width/2-35,299);
  vertex(width/2-44,297);
  endShape(CLOSE);
  beginShape();
  stroke(#f6fdf5);
  fill(#f6fdf5);
  vertex(width/2+42,297);
  bezierVertex(width/2+46,360,width/2+48,375,width/2+40,380);
  bezierVertex(width/2+35,375,width/2+38,378,width/2+35,370);
  bezierVertex(width/2+38,360,width/2+38,355,width/2+34,299);
  endShape(CLOSE);

效果如下
在这里插入图片描述

添加一点点的交互

到上一步为止,我的自画像已经基本完成了,但是既然是编程绘画,总得有与普通绘画不同之处,所以在这里添加一点点的鼠标交互:
我们在点击鼠标的时候,“我”的表情会发生改变。
为此使用一个全局变量flag,鼠标点击画时,flag的值就发生改变,为0时“我”微笑,为“1”时我冷漠。

添加鼠标点击函数

void mouseClicked() {

if(flag==0)
{
  flag=1;
}
else if(flag==1)
{
  flag=0;
}
} 

更改画眼睛,嘴巴等的代码

 //shy_red
  if(flag==0)
  {
  fill(#fac9b8);
  stroke(#fac9b8);
  ellipse(width/2-30,225,18,18);
  ellipse(width/2+30,225,18,18);
  }
  
  //mouse
  if(flag==0)
  {
  noFill();
  stroke(#bca497);
  strokeWeight(1);
  bezier(width/2-10, 230, width/2,235,width/2,235, width/2+10, 230);
  }
  else if(flag==1)
  {
   noFill();
  stroke(#bca497);
  strokeWeight(1);
  line(width/2-8,230,width/2+8,230);
  }
  //eyes
  if(flag==0)
  {
  fill(#939387);
  stroke(#939387);
  ellipse(width/2-30,200,20,18);
  ellipse(width/2+30,200,20,18);
  }
  else
  {
  fill(#939387);
  stroke(#939387);
  ellipse(width/2-30,200,20,10);
  ellipse(width/2+30,200,20,10);
  }

添加一点人物心里细节

if(flag==0)
   {
   drawDialog();   
   }
void drawDialog()
{
  stroke(#fcfcf4);
  fill(#fcfcf4);
  ellipse(width/2-100,250,20,10);
  ellipse(width/2-130,200,90,40);
  fill(#67675d);
  text("晚上吃什么呢?", width/2-168, 190, width/2+90, 240);
}

加上阴影,阴影绘制要在背景之后,物体之前

  //shadow
  stroke(#a5c3b7);
  fill(#a5c3b7);
  ellipse(width / 2+200, height/2+100,120,50);
  ellipse(width / 2+130, height/2+50,50,15);
  ellipse(width / 2-150, height/2+100,50,15);
  ellipse(width / 2-200, height/2+400,120,50);

结果展示

到这一步,自画像终于画好了!现在来看看效果。
在这里插入图片描述

体会

用代码画画最难的是调节线条的参数,再者直接手绘不用考虑线条生成的原理,而用代码画画要考虑每一种线条和图案生成的方法,然后用数学的方式来表现。
但是用不生动的代码画出可爱的画,看到最后的成果,我心里还是很开心的。

  • 10
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值