創意編程——振盪

基於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();
      
    }
  }

效果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章