本篇博客主要介绍如何用代码加上一些简单的数学函数来生成图形。
第一幅图形
图形介绍
用编程方式临摹下图,大家可以看到,下图主要是使用一些简单的数学函数来生成的动图。
用到的数学函数有以下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=2;
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;