[Processing和P5.js]简单动态图形临摹和拓展

[Processing和P5.js]简单动态图形临摹和拓展

在这里先说一下,本篇里做的两张动态图形,分别用了processing和p5.js,两者之前差异不大,所以明白了一种之后另一种也就比较好掌握了,但是p5.js相对来说可能更为简单一点。

原版动态图

[Processing和P5.js]简单动态图形临摹和拓展_第1张图片
由蒙德里安的作品演变形成的动态图

动态图临摹

观察动图组成及其运动规律

图片的主要构成就是长方形,但是如果把每个长方形都做出来,工作量就实在是太大了,所以就先计算图形四周主要顶点的坐标,然后用直线来进行图片的分割,至于说带有颜色的部分,就直接运用长方形的的函数来进行添加就好了。
相关代码如下:(这里用的processing)

void setup() {
  size(640, 640);
}

void draw(){
  strokeWeight(5);
  fill(255);
  rect(10,20,620,580);
  fill(255);
  rect(30,20,20,580);
  rect(590,20,20,580);
  drawline();
  colorrect();
  activerect();
  smallrect();
}

void drawline(){//画直线分割界面
  stroke(0); 
  line(10,20,630,20);
  line(10,40,630,40);
  line(10,580,630,580); 
  line(10,600,630,600);
  line(50,280,630,280);
  line(50,310,630,310);
  line(50,340,210,340);
  line(210,20,210,600);
  line(230,20,230,600);
  line(420,20,420,600);
  line(360,20,360,600);
  line(420,480,590,480);
  line(10,20,10,600);
  line(630,20,630,600);
}

void colorrect(){//添加带颜色的长方形到指定位置
  fill(255,0,0);
  rect(210,20,20,20);
  rect(50,40,160,240);
  rect(230,580,130,20);
  rect(360,580,60,20);
  rect(610,40,20,20);
  rect(10,230,20,210);
  fill(0,0,255);
  rect(10,580,20,20);
  rect(420,20,170,20);
  fill(255,255,0);
  rect(360,20,60,20);
  rect(360,40,60,260);
  rect(360,280,60,30);
  rect(210,580,20,20);
  rect(610,480,20,100);
  rect(420,480,170,100);
}

对于图中几个运动的长方形,观察其运动规律,可发现三者在y轴上均符合正弦变化,中间的小长方形可以看做在x轴上做正弦变化,并且其在y轴上的运动也是和两侧的运动长方形处于相对静止的关系,所以代码如下:

void activerect(){
  float m=millis()/200;
  fill(0,0,255);
  rect(30,260+220*sin(m),20,100);
  rect(590,260+220*sin(m),20,100);
}

void smallrect(){
  
  float t=millis()/200; 
   float x=310+270*sin(t),y=260+220*sin(t);
  fill(0);
  rect(x,y,20,20);
}

动图临摹结果

[Processing和P5.js]简单动态图形临摹和拓展_第2张图片
(请忽略图中鼠标的存在!!!录屏的时候没有注意到!!!抱歉!!!)

动态图拓展

原版的动态图实现了一种“打方块”游戏的感觉,而我写的则是使用代码强行感觉像是在碰撞,所以关于拓展我便想实现小方块之间碰撞的问题。
关于碰撞的问题就涉及到一个物理模型的问题,即碰撞之后小方块角度的变化和运动方向的变化,主要函数就是 SmallRect函数(这里我是做了一些参考,原本写出来的碰撞效果很不自然):
colide中,对两个方块之间的距离和边长50做比较,如果距离小于边长就代表发生了碰撞,然后求出加速度,对两方块速度进行改变。
函数move中,就是在物体发生碰撞之后改变物体的速度方向,
函数display则是调用画矩形的函数。
主要函数参考: https://blog.csdn.net/qq_40346122/article/details/83832420
所以根据案例的方法,我做了些碰撞的参考然后做了一些修改,使其满足我需要的碰撞规律,整体代码如下:(这里用的p5.js)

var numRects = 20;
var gravity = 0.03;
var friction = -0.9;
var smallrect=[];

function setup() {
  createCanvas(630, 600);
   strokeWeight(5);
  
  for(var i=0;i<numRects;i++){
    smallrect[i]=new SmallRect(
      random(width),
      random(height),
      random(50),     
      i,
      smallrect
    );
  }
  
}

function draw(){
  colorrect();
  drawline(); 
  activerect();
  fill(0);
  smallrect.forEach(rect=>{
    rect.collide();
    rect.move();
    rect.display();
  })
 
  
}

function drawline(){
  stroke(0); 
  line(10,20,630,20);
  line(10,40,630,40);
  line(10,580,630,580); 
  line(10,600,630,600);
  line(50,280,630,280);
  line(50,310,630,310);
  line(50,340,210,340);
  line(210,20,210,600);
  line(230,20,230,600);
  line(420,20,420,600);
  line(360,20,360,600);
  line(420,480,590,480);
  line(10,20,10,600);
  line(630,20,630,600);
}

function colorrect(){
  fill(255);
  rect(10,20,620,580);  
  fill(255);
  rect(30,20,20,580);
  rect(590,20,20,580);
  fill(255,0,0);
  rect(210,20,20,20);
  rect(50,40,160,240);
  rect(230,580,130,20);
  rect(360,580,60,20);
  rect(610,40,20,20);
  rect(10,230,20,210);
  fill(0,0,255);
  rect(10,580,20,20);
  rect(420,20,170,20);
  fill(255,255,0);
  rect(360,20,60,20);
  rect(360,40,60,260);
  rect(360,280,60,30);
  rect(210,580,20,20);
  rect(610,480,20,100);
  rect(420,480,170,100);
}

function activerect(){
  var m=millis()/150;
  fill(0,0,255);
  rect(30,260+220*sin(m),20,100);
  rect(590,260+220*sin(m),20,100);
}

function SmallRect(x,y,dis,id,other){
  this.x = x;
  this.y = y;
  var vx = 0;
  var vy = 0;
  this.long = dis;
  this.id = id;
  this.others =other;
  
  this.collide=function(){
     for (var i = this.id + 1; i < numRects; i++) {
      // console.log(others[i]);
      var dx = this.others[i].x - this.x;
      var dy = this.others[i].y - this.y;
      var distance = sqrt(dx * dx + dy * dy);

      if (distance <50) {
        var angle = atan2(dy, dx);
        var targetX = this.x + cos(angle) *50;
        var targetY = this.y + sin(angle) *50;
        var ax = (targetX - this.others[i].x) *0.05;
        var ay = (targetY - this.others[i].y) * 0.05;
        vx -= ax;
        vy -= ay;
        this.others[i].vx += ax;
        this.others[i].vy += ay;

      }
    }
  };
  
  this.move = function() {
    vy += gravity;
    this.x += vx;
    this.y += vy;
    if (this.x + this.long/ 2 > width) {
      this.x = width - this.long/ 2;
      vx *= friction;
		 
    } else if (this.x - this.long/ 2 < 0) {
      this.x = this.long/ 2;
      vx *= friction;		 
    }
    if (this.y + this.long/ 2 > height) {
      this.y = height - this.long/ 2;
      vy *= friction;
	 
    } else if (this.y - this.long/ 2 < 0) {
      this.y = this.long/ 2;
      vy *= friction;
	 
    }
  };
	 

  this.display = function() {
    rect(this.x, this.y, 50,50);
  };
}

动图拓展结果

你可能感兴趣的:([Processing和P5.js]简单动态图形临摹和拓展)