第3章 振荡——《processing》学习,自己完成实验的代码

第四个实验的完成结果为:
在这里插入图片描述
主函数显示为:

Spaceship ship;
Bob b1;
Bob b2;
Bob b3;

Spring s1;
Spring s2;
Spring s3;

newmover[] movers = new newmover[30];
Attractor a;

float startAngle = 0;
float angleVel = 0.23;

void setup() {
  size(840, 560);
  ship = new Spaceship();
  
  b1 = new Bob(width/5, 200);
  b2 = new Bob(width/6, 300);
  b3 = new Bob(width/4, 500);

  s1 = new Spring(b1,b2,100);
  s2 = new Spring(b2,b3,100);
  s3 = new Spring(b1,b3,100);
  
  /*attractor*/
  for (int i = 0; i < movers.length; i++) {
    movers[i] = new newmover(random(0.1,2),random(width),random(height)); 
  }
  a = new Attractor();
}

void draw() {
  background(39,64,139); 
  
   /**wave**/
  startAngle += 0.035;
  float angle = startAngle;

 for (int x = 0; x <= width; x += 24) {
    float y = map(sin(angle),-1,1,height*4/5,height);
    noStroke();
    fill(238,233,233,120);
    ellipse(x,y,30,30);
    angle += angleVel;
  } 
  
  for (int x = 0; x <= width; x +=24) {
    float y = map(sin(angle),-1,1,height*4/5,height);
    noStroke();
    fill(238,233,233,120);
    ellipse(x,y,30,30);
    angle += angleVel;
  } 
 
  /*拉扯星球*/
  s1.update();
  s2.update();
  s3.update();
  
  s1.display();
  s2.display();
  s3.display();

  b1.update();
  b1.display2();
  
  b2.update();
  b2.display();
  b3.update();
  b3.display();

  b1.drag(mouseX, mouseY);
  
  /*attractor*/
  a.drag();
  a.hover(mouseX,mouseY);//拖拽中心物体
  a.display();

  for (int i = 0; i < movers.length; i++) {
    PVector force = a.attract(movers[i]);
    movers[i].applyForce(force);

    movers[i].update();
    movers[i].display();
  }
   /*SPACESHIP*/
  // Update position
  ship.update();
  // Wrape edges
  ship.wrapEdges();
  // Draw ship
  ship.display();
   
  fill(0);
  text("First click !and then Left Right arrows to turn, Up to thrust",10,height-5);
  text("首先点击屏幕!左右控制方向转向,上键飞船启动",10,height-20);
  // Turn or thrust the ship depending on what key is pressed
  if (keyPressed) {
    if (key == CODED && keyCode == LEFT) {
      ship.turn(-0.03);
    } else if (key == CODED && keyCode == RIGHT) {
      ship.turn(0.03);
    } else if (key == CODED && keyCode == UP) {
      ship.thrust(); 
    }
  }
}

void mousePressed() {
  b1.clicked(mouseX, mouseY);
  a.clicked(mouseX, mouseY);
}

void mouseReleased() {
  b1.stopDragging();
  a.stopDragging();
}

在这里插入图片描述
引用类Mover

class Bob { 
  PVector position;
  PVector velocity;
  PVector acceleration;
  float mass = 12;
  
  // Arbitrary damping to simulate friction / drag 
  float damping = 0.95;

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

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

  // Standard Euler integration
  void update() { 
    velocity.add(acceleration);
    velocity.mult(damping);
    position.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(255,222,173);
    strokeWeight(2);
    fill(255,215,0);
    if (dragging) {
      strokeWeight(4);
      fill(255,106,106);
    }
    ellipse(position.x,position.y,mass*2,mass*2);
  } 
  void display2() { 
    stroke(255,0,173);
    strokeWeight(2);
    fill(255,215,0);
    if (dragging) {
      strokeWeight(4);
      fill(255,106,106);
    }
    ellipse(position.x,position.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,position.x,position.y);
    if (d < mass) {
      dragging = true;
      dragOffset.x = position.x-mx;
      dragOffset.y = position.y-my;
    }
  }

  void stopDragging() {
    dragging = false;
  }

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

SpaceShip代码:

class Spaceship { 
  // All of our regular motion stuff
  PVector position;
  PVector velocity;
  PVector acceleration;

  // Arbitrary damping to slow down ship
  float damping = 0.995;
  float topspeed = 6;

  // Variable for heading!
  float heading = 0;

  // Size
  float r = 40;

  // Are we thrusting (to color boosters)
  boolean thrusting = false;

  Spaceship() {
    position = new PVector(width/2,height/2);
    velocity = new PVector();
    acceleration = new PVector();
  } 

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

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

  // Turn changes angle
  void turn(float a) {
    heading += a;
  }
  
  // Apply a thrust force
  void thrust() {
    float angle = heading - PI/2;
    PVector force = new PVector(cos(angle),sin(angle));
    force.mult(0.1);
    applyForce(force); 
    // To draw booster
    thrusting = true;
  }

  void wrapEdges() {
    float buffer = r*2;
    if (position.x > width +  buffer) position.x = -buffer;
    else if (position.x <    -buffer) position.x = width+buffer;
    if (position.y > height + buffer) position.y = -buffer;
    else if (position.y <    -buffer) position.y = height+buffer;
  }
  // Draw the ship
  void display() { 
    stroke(0);
    strokeWeight(2);
    pushMatrix();
    translate(position.x,position.y+r);
    rotate(heading);
    fill(175);
    if (thrusting) fill(255,0,0);
    // Booster rockets
    rect(-r/2,r,r/3,r/2);
    rect(r/2,r,r/3,r/2);
    fill(240,255,255);
    // A triangle
    beginShape();
    vertex(-r,r);
    vertex(0,-r);
    vertex(r,r);
    endShape(CLOSE);
    rectMode(CENTER);
    popMatrix();
    
    thrusting = false;
  }
}

Spring类的代码

class Spring { 

  PVector anchor;

  float len;
  float k = 0.2;
  
  Bob a;
  Bob b;

  // Constructor
  Spring(Bob a_, Bob b_, int l) {
    a = a_;
    b = b_;
    len = l;
  } 

  void update() {
    // Vector pointing from anchor to bob position
    PVector force = PVector.sub(a.position, b.position);
    // What is distance
    float d = force.mag();
    // Stretch is difference between current distance and rest length
    float stretch = d - len;

    force.normalize();
    force.mult(-1 * k * stretch);
    a.applyForce(force);
    force.mult(-1);
    b.applyForce(force);
  }
  void display() {
    strokeWeight(2);
    stroke(0);
    line(a.position.x, a.position.y, b.position.x, b.position.y);
  }
}

Attractor类的代码:

// A class for a draggable attractive body in our world
class Attractor {
  float mass;         // Mass, tied to size
  PVector position;   // position
  float g;
  boolean dragging = false; // Is the object being dragged?
  boolean rollover = false; // Is the mouse over the ellipse?
  PVector dragOffset;  // holds the offset for when object is clicked on

  Attractor() {
    position = new PVector(width*3/4, height/4);
    mass = 20;
    g = 0.4;
    dragOffset = new PVector(0.0,0.0);
  }

  PVector attract(newmover m) {
    PVector force = PVector.sub(position, m.position);             // Calculate direction of force
    float distance = force.mag();                                 // Distance between objects
    distance = constrain(distance, 5.0, 25.0);                             // Limiting the distance to eliminate "extreme" results for very close or very far objects
    force.normalize();                                            // Normalize vector (distance doesn't matter here, we just want this vector for direction)
    float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude
    force.mult(strength);                                         // Get force vector --> magnitude * direction
    return force;
  }

  // Method to display
  void display() {
    stroke(255,255,255,120);
    strokeWeight(6);
    if (dragging) fill (50);
    else if (rollover) fill(100);
    else fill(0,191,255);
    ellipse(position.x, position.y, 70, 70);
  }
  //mouse interaction
    void clicked(int mx, int my) {
    float d = dist(mx,my,position.x,position.y);
    if (d < mass) {
      dragging = true;
      dragOffset.x = position.x-mx;
      dragOffset.y = position.y-my;
    }
  }

  void hover(int mx, int my) {
    float d = dist(mx,my,position.x,position.y);
    if (d < mass) {
      rollover = true;
    } 
    else {
      rollover = false;
    }
  }

  void stopDragging() {
    dragging = false;
  }

  void drag() {
    if (dragging) {
      position.x = mouseX + dragOffset.x;
      position.y = mouseY + dragOffset.y;
    }
  } 
}

newmover类——被Attractor所吸引。

class newmover {

  PVector position;
  PVector velocity;
  PVector acceleration;
  float mass;

  float angle = 0;
  float aVelocity = 0;
  float aAcceleration = 0;

  newmover(float m, float x, float y) {
    mass = m;
    position = new PVector(x,y);
    velocity = new PVector(random(-1,1),random(-1,1));
    acceleration = new PVector(0,0);
  }

  void applyForce(PVector force) {
    PVector f = PVector.div(force,mass);
    acceleration.add(f);
  }

  void update() {

    velocity.add(acceleration);
    position.add(velocity);

    aAcceleration = acceleration.x / 10.0;
    aVelocity += aAcceleration;
    aVelocity = constrain(aVelocity,-0.1,0.1);
    angle += aVelocity;

    acceleration.mult(0);
  }

  void display() {
    noStroke();
    //fill(255,130,171,230);
    float g = random(255);
   /* float sd = 20; float mean = 200;*/
    /*g = constrain(g,0,255);*/
    fill(255,g,50);
    rectMode(CENTER);
    pushMatrix();
    translate(position.x,position.y);
    rotate(angle);
    rect(0,0,mass*16,mass*16);
    popMatrix();
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值