p5.js 动态图形临摹

本篇博客主要介绍如何用代码加上一些简单的数学函数来生成图形。

第一幅图形

图形介绍

用编程方式临摹下图,大家可以看到,下图主要是使用一些简单的数学函数来生成的动图。
用到的数学函数有以下13种:

在这里插入图片描述
在这里插入图片描述

实现过程

为了方便画图,首先把坐标原点移到画布中央位置,设置线宽、背景色

其中获取程序运行的时间用来实现图像的运动。(单位为:毫秒)

let millisecond = millis();
function setup() {
  createCanvas(400, 400);
}

let num=0;
let millisecond1 = 0;
let h=200;
let w=200;
let flag=0;
function draw() {
  let parameter=1;
  background(255);
  strokeWeight(4);
  translate(h, w);
  let millisecond = millis();

下面开始实现

用简单的线条画出人物的形状

//身体
  arc(0, 13, 45, 75, 0, 2*PI);
  //头
  circle(0,-50,50);
  if(millisecond1<500)
  {
    //腿
    line(-10,48,-30,90);
    line(-30,90,-20,125);
    line(10,48,20,125);
    //脚
    line(-20,125,-40,135);
    line(20,125,40,135);
  }
  else if(millisecond1>3000&&millisecond1<3500)
  {
    //腿
    line(10,48,30,90);
    line(30,90,20,125);
    line(-10,48,-20,125);
    //脚
    line(20,125,40,135);
    line(-20,125,-40,135);
  }
    else 
  {
    //腿
    line(10,48,20,125);
    line(-10,48,-20,125);
    //脚
    line(20,125,40,135);
    line(-20,125,-40,135);
  }
  //眼睛
  circle(10,-55,5);
  circle(-10,-55,5);
  //嘴巴
  arc(0, -45, 15, 10, 0, PI);
  //耳朵
  arc(-25, -47, 10, 10, HALF_PI, PI+HALF_PI);
  arc(25, -47, 10, 10, -HALF_PI, HALF_PI);
  //头发
  line(0,-75,-15,-90);
}

第一个函数实现:

  //y=-|x|
  if(millisecond1<500.0)
  {
    line(5,-25,55,25);
    line(-5,-25,-55,25);
  }

第二个函数实现:

  //y=pow(x,2)
  else if(millisecond1<1500.0)
  for(x;x<8;x+=0.1){
    line(x*7,-(x*x)-25,(x+0.1)*7,-((x+0.1)*(x+0.1)+25));
    line(-x*7,-(x*x)-25,-(x+0.1)*7,-((x+0.1)*(x+0.1)+25));
    }

第三个函数实现:

//y=pow(x,3)
  else if(millisecond1<2000.0)
    for(x;x<4;x+=0.1){
    line(x*13,-(pow(x,3))-25,(x+0.1)*13,-(pow((x+0.1),3)+25));
    line(-x*13,(pow(x,3))-25,-(x+0.1)*13,(pow((x+0.1),3)-25));
    }

第四个函数实现:

//y=pow(x,-1)
  else if(millisecond1<2500.0)
    for(x;x<0.5;x+=0.02){
    line(x*100,-(pow(x,-1))-25,(x+0.1)*100,-(pow((x+0.1),-1)+25));
    line(-x*100,pow(x,-1)-25,-(x+0.1)*100,pow((x+0.1),-1)-25);
    }

第五个函数实现:

//y=-pow(x,-1)
  else if(millisecond1<3000.0)
    for(x;x<0.5;x+=0.02){
    line(-x*100,-(pow(x,-1))-25,-(x+0.1)*100,-(pow((x+0.1),-1)+25));
    line(x*100,pow(x,-1)-25,(x+0.1)*100,pow((x+0.1),-1)-25);
    }

第六个函数实现:

//y=log(x)
  else if(millisecond1<3500.0)
    for(x;x<50;x+=0.02){
    line(x*3-70,4*log(x)-36,(x+0.1)*3-70,4*log(x+0.1)-36);
    }

第七个函数实现:

//y=pow(a,x) 采取y=log(x)的对称
  else if(millisecond1<4000.0)
    for(x;x<50;x+=0.02){
    line(-x*3+70,4*log(x)-36,-(x+0.1)*3+70,4*log(x+0.1)-36);
    }

第八个函数实现:

  //y=sin(x)
  else if(millisecond1<4500.0)
   for(x=-1.0;x<3.14;x+=0.02){
    line(x*15+22,sin(x)*15-10,(x+0.1)*15+22,sin(x+0.1)*15-10);
    line(-x*15-22,-sin(x)*15-35,-(x+0.1)*15-22,-sin(x+0.1)*15-35);
   }

第九个函数实现:

  //y=cos(x)
  else if(millisecond1<5000.0)
  for(x=-0.5;x<3.14;x+=0.02){
    line(x*15+15,-cos(x)*15-10,(x+0.1)*15+15,-cos(x+0.1)*15-10);
    line(-x*15-15,-cos(x)*15-10,-(x+0.1)*15-15,-cos(x+0.1)*15-10);
  }

第十个函数实现:

  //pow(x,2)+pow(y,2)=pow(r,2)
  else if(millisecond1<5500.0)
  {
    noFill();
    circle(0,-65,80);
  }

第十一个函数实现:

  //y=x
  else if(millisecond1<6000.0)
  {
    line(10,-25,60,-75);
  line(-60,25,-10,-25);
  }

第十二个函数实现:

  //y=-x
  else if(millisecond1<6500.0)
  {
     line(-10,-25,-60,-75);
   line(60,25,10,-25);
  }

第十三个函数实现:

  //y=|x|
  else if(millisecond1<7000.0)
  {
    line(-10,-25,-60,-75);
    line(10,-25,60,-75);
  }

运行结果

运行结果如下图所示:

在这里插入图片描述
通过不停的坐标转换来实现运动效果,代码中通过改变h的值来实现此效果:

 if(h<=350&&flag==0)
  {
    h+=parameter;
    if(h==350)
      flag=1;
  }
  if(h>=50&&flag==1)
  {
    h-=parameter;
    if(h==50)
      flag=0;
  }

实现运动后,突发奇想,试着改变一下小人的移动速来看一下会有怎样的效果,通过定义parameter来表示人物的运动的相对速度

let parameter=1;

下面是不同parameter对应的运动效果:
parameter=1;
parameter=1

parameter=2;
parameter=2

parameter=5;
parameter=5

parameter=10;
在这里插入图片描述

parameter=25;
在这里插入图片描述

parameter=75;
在这里插入图片描述

parameter=150;
在这里插入图片描述

全部代码

// An highlighted block
function setup() {
  createCanvas(400, 400);
}

let num=0;
let millisecond1 = 0;
let h=200;
let w=200;
let flag=0;
function draw() {
  let parameter=1;
  if(h<=350&&flag==0)
  {
    h+=parameter;
    if(h==350)
      flag=1;
  }
  if(h>=50&&flag==1)
  {
    h-=parameter;
    if(h==50)
      flag=0;
  }
  background(255);
  strokeWeight(4);
  translate(h, w);
  let millisecond = millis();
  stroke(62,188,202);
  millisecond1 = millisecond -7000*num;
  //print(millisecond1);
  //身体
  arc(0, 13, 45, 75, 0, 2*PI);
  //头
  circle(0,-50,50);
  if(millisecond1<500)
  {
    //腿
    line(-10,48,-30,90);
    line(-30,90,-20,125);
    line(10,48,20,125);
    //脚
    line(-20,125,-40,135);
    line(20,125,40,135);
  }
  else if(millisecond1>3000&&millisecond1<3500)
  {
    //腿
    line(10,48,30,90);
    line(30,90,20,125);
    line(-10,48,-20,125);
    //脚
    line(20,125,40,135);
    line(-20,125,-40,135);
  }
    else 
  {
    //腿
    line(10,48,20,125);
    line(-10,48,-20,125);
    //脚
    line(20,125,40,135);
    line(-20,125,-40,135);
  }
  //眼睛
  circle(10,-55,5);
  circle(-10,-55,5);
  //嘴巴
  arc(0, -45, 15, 10, 0, PI);
  //耳朵
  arc(-25, -47, 10, 10, HALF_PI, PI+HALF_PI);
  arc(25, -47, 10, 10, -HALF_PI, HALF_PI);
  //头发
  line(0,-75,-15,-90);

  let x=0;
  //y=-|x|
  //stroke('red');
  if(millisecond1<500.0)
  {
    line(5,-25,55,25);
    line(-5,-25,-55,25);
  }
  else if(millisecond1<580.0)
  {
    line(6,-25,56,15);
    line(-6,-25,-56,15);
  }
  else if(millisecond1<660.0)
  {
    line(7,-25,57,0);
    line(-7,-25,-57,0);
  }
  else if(millisecond1<740.0)
  {
    line(8,-25,58,-15);
    line(-8,-25,-58,-15);
  }
  else if(millisecond1<820.0)
  {
    line(9,-25,59,-25);
    line(-9,-25,-59,-25);
  }
  else if(millisecond1<1000.0)
  {
    line(8,-25,58,-50);
    line(-8,-25,-58,-50);
  }
  //y=pow(x,2)
  else if(millisecond1<1500.0)
  for(x;x<8;x+=0.1){
    line(x*7,-(x*x)-25,(x+0.1)*7,-((x+0.1)*(x+0.1)+25));
    line(-x*7,-(x*x)-25,-(x+0.1)*7,-((x+0.1)*(x+0.1)+25));
    }
  //y=pow(x,3)
  else if(millisecond1<2000.0)
    for(x;x<4;x+=0.1){
    line(x*13,-(pow(x,3))-25,(x+0.1)*13,-(pow((x+0.1),3)+25));
    line(-x*13,(pow(x,3))-25,-(x+0.1)*13,(pow((x+0.1),3)-25));
    }
  //y=pow(x,-1)
  else if(millisecond1<2500.0)
    for(x;x<0.5;x+=0.02){
    line(x*100,-(pow(x,-1))-25,(x+0.1)*100,-(pow((x+0.1),-1)+25));
    line(-x*100,pow(x,-1)-25,-(x+0.1)*100,pow((x+0.1),-1)-25);
    }
  //y=-pow(x,-1)
  else if(millisecond1<3000.0)
    for(x;x<0.5;x+=0.02){
    line(-x*100,-(pow(x,-1))-25,-(x+0.1)*100,-(pow((x+0.1),-1)+25));
    line(x*100,pow(x,-1)-25,(x+0.1)*100,pow((x+0.1),-1)-25);
    }
  //y=log(x)
  else if(millisecond1<3500.0)
    for(x;x<50;x+=0.02){
    line(x*3-70,4*log(x)-36,(x+0.1)*3-70,4*log(x+0.1)-36);
    }
  //y=pow(a,x) 采取y=log(x)的对称
  else if(millisecond1<4000.0)
    for(x;x<50;x+=0.02){
    line(-x*3+70,4*log(x)-36,-(x+0.1)*3+70,4*log(x+0.1)-36);
    }
  
  //y=sin(x)
  else if(millisecond1<4500.0)
   for(x=-1.0;x<3.14;x+=0.02){
    line(x*15+22,sin(x)*15-10,(x+0.1)*15+22,sin(x+0.1)*15-10);
    line(-x*15-22,-sin(x)*15-35,-(x+0.1)*15-22,-sin(x+0.1)*15-35);
   }
  
  //y=cos(x)
  else if(millisecond1<5000.0)
  for(x=-0.5;x<3.14;x+=0.02){
    line(x*15+15,-cos(x)*15-10,(x+0.1)*15+15,-cos(x+0.1)*15-10);
    line(-x*15-15,-cos(x)*15-10,-(x+0.1)*15-15,-cos(x+0.1)*15-10);
  }
  
  //pow(x,2)+pow(y,2)=pow(r,2)
  else if(millisecond1<5500.0)
  {
    noFill();
    circle(0,-65,80);
  }
  
  //y=x
  else if(millisecond1<6000.0)
  {
    line(10,-25,60,-75);
  line(-60,25,-10,-25);
  }
  
  //y=-x
  else if(millisecond1<6500.0)
  {
     line(-10,-25,-60,-75);
   line(60,25,10,-25);
  }
  
  //y=|x|
  else if(millisecond1<7000.0)
  {
    line(-10,-25,-60,-75);
    line(10,-25,60,-75);
  }
  else
  {
    num=num+1;
    print(num);
  }
  
}

第二幅图形

图形介绍

该图形是由大小不同的圆通过做直线变速运动形成。
在这里插入图片描述

实现过程

首先实现单个圆形体,函数中(x,y)表示圆心坐标。

function pic1(x,y){
  let r = 400;
  let i = 0;
  for(i;i<400;i=i+40){
    circle(x,y,r-i);
  }
}

在画布上画出图形

let num1=0;
let num2=400;
let flag1= false;
let flag2= false;
function setup() {

}

function draw() {
  createCanvas(400, 400)
  background(255)
  noFill()
  strokeWeight(15)
  pic1(num1,200)
  pic1(num2,200)
}

通过flag的变化来实现图形的左右运动,f对于num1对应的图形flag为假是向右运动,为真时向左运动。另一个图型相反。通过更改num1每次的变化数值来实现速度的变化,可以观察到,圆形体在运行到边缘时有明显的减速过程,通过修改num1每次的变化数值为1实现减速的效果。

let parameter=4;
if(!flag1){
  if(num1<380)
    num1+=parameter;
  else
    num1+=1;
  if(num1==400)
    flag1 = true;
}
if(flag1){
  if(num1>20)
    num1-=parameter;
  else
    num1-=1;
  if(num1==0)
    flag1 = false;
}

if(!flag2){
  if(num2>20)
    num2-=parameter;
  else
    num2-=1;
  if(num2==0)
    flag2 = true;
}
if(flag2){
  if(num2<380)
    num2+=parameter;
  else
    num2+=1;
  if(num2==400)
    flag2 = false;
}

运行结果

运行结果如下图所示:

parameter=4时,和原图效果差不多
在这里插入图片描述

下面是不同parameter对应的运动效果:
parameter=8;
在这里插入图片描述

parameter=20;
在这里插入图片描述
parameter=40;
在这里插入图片描述
parameter=65;
在这里插入图片描述
parameter=80;
parameter=100;
在这里插入图片描述
parameter=200;
在这里插入图片描述

发布了20 篇原创文章 · 获赞 7 · 访问量 7075

猜你喜欢

转载自blog.csdn.net/YCSDNG/article/details/102668307