创意编程——振荡

基于processing实现

效果演示

10个粒子

30个粒子
在这里插入图片描述

60个粒子
在这里插入图片描述

Processing实现

可拖拽震荡粒子(参考)

在这里插入图片描述

class Bob { 
  PVector location;
  PVector velocity;
  PVector acceleration;
  float mass = 24;
  
  // Arbitrary damping to simulate friction / drag 
  float damping = 0.98;

  // For mouse interaction
  PVector dragOffset;
  boolean dragging = false;

  // Constructor
  Bob(float x, float y) {
    location = new PVector(x,y);
    velocity = new PVector();
    acceleration = new PVector();
    dragOffset = new PVector();
  } 

  // Standard Euler integration
  void update() { 
    velocity.add(acceleration);
    velocity.mult(damping);
    location.add(velocity);
    acceleration.mult(0);
  }

  // Newton's law: F = M * A
  void applyForce(PVector force) {
    PVector f = force.get();
    f.div(mass);
    acceleration.add(f);
  }


  // Draw the bob
  void display() { 
    stroke(0);
    strokeWeight(2);
    fill(175);
    if (dragging) {
      fill(50);
    }
    ellipse(location.x,location.y,mass*2,mass*2);
  } 

  // The methods below are for mouse interaction

  // This checks to see if we clicked on the mover
  void clicked(int mx, int my) {
    float d = dist(mx,my,location.x,location.y);
    if (d < mass) {
      dragging = true;
      dragOffset.x = location.x-mx;
      dragOffset.y = location.y-my;
    }
  }

  void stopDragging() {
    dragging = false;
  }

  void drag(int mx, int my) {
    if (dragging) {
      location.x = mx + dragOffset.x;
      location.y = my + dragOffset.y;
    }
  }
}

固定位移振荡(参考)

在这里插入图片描述

class Oscillator {   

  PVector angle;
  PVector velocity;
  PVector amplitude;

  Oscillator() {   
    angle = new PVector();
    velocity = new PVector(random(-0.05, 0.05), random(-0.05, 0.05));
    amplitude = new PVector(random(20,width/2), random(20,height/2));
  }   

  void oscillate() {
    angle.add(velocity);
  }   

  void display() {   

    float x = sin(angle.x)*amplitude.x;
    float y = sin(angle.y)*amplitude.y;

    pushMatrix();
    translate(width/2, height/2);
    stroke(0);
    strokeWeight(2);
    fill(127,127);
    line(0, 0, x, y);  
    ellipse(x, y, 32, 32);  
    popMatrix();
  }
}   

固定位移可拖拽振荡粒子

优化1

Oscillator类中添加clicked,stopDragging,drag函数,分别进行点击相应,拖拽响应与停止拖拽响应。

void clicked(int mx, int my) {
    print(1);
    float x = sin(angle.x)*amplitude.x;
    float y = sin(angle.y)*amplitude.y;
    
    mx = mx - width/2;
    my = my - height/2;
    
    float d = dist(mx,my,x,y);
    
    if (d < mass) {
      dragging = true;
      dragOffset.x = x-mx - width/2;
      dragOffset.y = y-my - height/2;
    }
  }

  void stopDragging() {
    dragging = false;
  }
  
  void drag(int mx, int my) {
    if (dragging) {
      
      //float x = sin(angle.x)*amplitude.x;
      //float y = sin(angle.y)*amplitude.y;
      
      float x = mx + dragOffset.x;
      float y = my + dragOffset.y;
      
      float new_x = asin(x/amplitude.x);
      if(!Double.isNaN(new_x)){
        angle.x = new_x;
      }
      
      float new_y = asin(y/amplitude.y);
      if(!Double.isNaN(new_y)){
        angle.y = new_y;
      }
      
      
      print(angle.x,angle.y);
      
      pushMatrix();
      translate(width/2, height/2);
      stroke(0);
      strokeWeight(2);
      fill(this.c);
      line(0, 0, x, y);  
       if(type==1){
        ellipse(x, y, 32, 32);  
      }
      else if(type==2){
        rect(x, y, 32, 32);  
      }
      else if(type==3){
        triangle(x+10, y+10, x-20, y-20, x-20, y+20);  
      }
      
      popMatrix();
      
    }
  }
  • 修改其显示函数,使其与被拖拽时效果不同,不显示边框;
  • 添加随机数type用来随机选择粒子的样式;
  • 随机生成每个粒子的颜色
  int type = 1;
  

  Oscillator() {   
    ...
    
    int max=4,min=1;
    type = (int) (Math.random()*(max-min)+min);

  }   
  
  
  void display() {   
    
    if (!dragging) {
      float x = sin(angle.x)*amplitude.x;
      float y = sin(angle.y)*amplitude.y;
  
      pushMatrix();
      translate(width/2, height/2);
      noStroke();
      //stroke(0);
      strokeWeight(2);
      fill(this.c);
      line(0, 0, x, y);  
      if(type==1){
        ellipse(x, y, 32, 32);  
      }
      else if(type==2){
        rect(x, y, 32, 32);  
      }
      else if(type==3){
        triangle(x+10, y+10, x-20, y-20, x-20, y+20);  
      }
      popMatrix();
    }
    
  }

效果

在这里插入图片描述

粒子系统

粒子系统就是一系列独立对象的集合, 这些对象通常用简单的图形或者点来表示。 为什么我们要学习粒子系统呢? 毫无疑问, 粒子系统可以用于模拟各种自然现象( 比如爆炸) 。 实际上, 它的作用不局限于此。如果我们要用代码对自然界的各种事物建模, 要接触的系统肯定并不是由单个物体组成的, 系统内部会有很多物体, 而粒子系统非常适合对复数系统进行建模。 比如一堆弹球的弹跳运动、 鸟群的繁殖, 以及生态系统的演化, 这些研究对象都是由复数组成的系统。本书的后续章节都会涉及对一组对象的处理。 在前面向量和力的示例程序中, 我们简单地用数组表示一组对象, 但从本章开始, 我们要用一种更强大的方式表示它们。首先, 列表中物体的数量应该是可变的: 可能没有物体, 可能只有1个物体, 也可能有10个物体或成千上万的物体。 其次, 除了定义粒子类, 我们还会定义一个类表示粒子的集合——也就是粒子系统( ParticleSystem) 类。

详见我之前写的博客创意编程——粒子与细胞分裂

效果

在这里插入图片描述

改进2

在每个粒子被拖拽时都使粒子系统生效

  void drag(int mx, int my) {
    if (dragging) {
      ...

      P.origin = new PVector(x, y);
      P.run();
      P.addParticle(this.c);
      
      popMatrix();
      
    }
  }

效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值