弹力

2022-05-04  本文已影响0人  大龙10

书名:代码本色:用编程模拟自然系统
作者:Daniel Shiffman
译者:周晗彬
ISBN:978-7-115-36947-5
目录

3.10 弹力

1、胡克定律

  弹簧的弹力可以根据胡克定律计算得到,胡克定律以英国物理学家罗伯特·胡克命名,他在1660年发明了这个公式。

请记住,弹力是一个向量,除了大小,我们还应该计算它的方向。

2、弹力的方向

在下面的代码中,我们用force变量表示弹力向量。

float k = 0.1; 按照胡克定律计算得到的弹力
PVector force = PVector.sub(bob,anchor);
float currentLength = dir.mag();
float x = restLength - currentLength;
force.normalize(); 弹力的方向(单位向量)
force.mult(-1 k x); 把方向和大小放在一起!

3、钟摆类

图3-18

如图3-18所示,钟摆类(bob)主要用于管理钟摆的运动;

4、弹簧类

弹簧类用于管理弹簧的枢轴点位置、静止长度和计算作用在钟摆上的弹力。

5、示例

示例代码3-11 弹簧连接

Bob bob;
Spring spring;

void setup() {
  size(640,360);
  // Create objects at starting position
  // Note third argument in Spring constructor is "rest length"
  spring = new Spring(width/2,10,100); 
  bob = new Bob(width/2,100); 
}

void draw()  {
  background(255); 
  // Apply a gravity force to the bob
  PVector gravity = new PVector(0,2);
  bob.applyForce(gravity);
  
  // Connect the bob to the spring (this calculates the force)
  spring.connect(bob);
  // Constrain spring distance between min and max
  spring.constrainLength(bob,30,200);
  
  // Update bob
  bob.update();
  // If it's being dragged
  bob.drag(mouseX,mouseY);
  
  // Draw everything
  spring.displayLine(bob); // Draw a line between spring and bob
  bob.display(); 
  spring.display(); 
  
  fill(0);
  text("click on bob to drag",10,height-5);
}


// For mouse interaction with bob
void mousePressed()  {
  bob.clicked(mouseX,mouseY);
}

void mouseReleased()  {
  bob.stopDragging(); 
}

mover.pde

// Bob class, just like our regular Mover (position, velocity, acceleration, mass)

class Bob { 
  PVector position;
  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) {
    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(0);
    strokeWeight(2);
    fill(0,175,0);
    if (dragging) {
      fill(50);
    }
    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;
    }
  }
}

Spring.pde

class Spring { 


  PVector anchor;    //弹簧的枢轴点位置

  float len;  //静止长度和相关常量
  float k = 0.3;

  // Constructor 在构造函数中初始化枢轴点和静止长度
  Spring(float x, float y, int l) {
    anchor = new PVector(x, y);
    len = l;
  } 

  // 计算弹力,实现胡克定律
  void connect(Bob b) {
    //  获取由枢轴点指向摆锤的向量
    PVector force = PVector.sub(b.position, anchor);
    // What is distance
    float d = force.mag();
    // 计算距离和静止长度的差值
    float stretch = d - len;

    // Calculate force according to Hooke's Law
    // F = k * stretch
    force.normalize();   //合并大小和方向
    force.mult(-1 * k * stretch);
    b.applyForce(force);   //调用applyForce()函数
  }

  // Constrain the distance between bob and anchor between min and max
  void constrainLength(Bob b, float minlen, float maxlen) {
    PVector dir = PVector.sub(b.position, anchor);
    float d = dir.mag();
    // Is it too short?
    if (d < minlen) {
      dir.normalize();
      dir.mult(minlen);
      // Reset position and stop from moving (not realistic physics)
      b.position = PVector.add(anchor, dir);
      b.velocity.mult(0);
      // Is it too long?
    } 
    else if (d > maxlen) {
      dir.normalize();
      dir.mult(maxlen);
      // Reset position and stop from moving (not realistic physics)
      b.position = PVector.add(anchor, dir);
      b.velocity.mult(0);
    }
  }

  void display() { 
    stroke(0);
    fill(0,175,0);
    strokeWeight(2);
    rectMode(CENTER);
    rect(anchor.x, anchor.y, 10, 10);
  }

  void displayLine(Bob b) {
    strokeWeight(2);
    stroke(0);
    line(b.position.x, b.position.y, anchor.x, anchor.y);
  }
}

6、运行效果

上一篇 下一篇

猜你喜欢

热点阅读