遗留的问题:排斥力如何实现

2022-07-01  本文已影响0人  Obj_Arr

原因

昨天在学习时发现缺少一些关键内容,所以就去找了作者提供的原始代码,看看是如何实现的。

代码

ParticleSystem ps;
Repeller repeller;

void setup() {
  size(800,200);
  smooth();
  ps = new ParticleSystem(new PVector(width/2,50));
  repeller = new Repeller(width/2-20,height/2);
}

void draw() {
  background(255);
  ps.addParticle();
  
  // Apply gravity force to all Particles
  PVector gravity = new PVector(0,0.1);
  ps.applyForce(gravity);
  *********关键部分************
  ps.applyRepeller(repeller);
  
  repeller.display();
  ps.run();
}
// Simple Particle System
// Daniel Shiffman <http://www.shiffman.net>

// A simple Particle class

class Particle {
  PVector location;
  PVector velocity;
  PVector acceleration;
  float lifespan;
  
  float mass = 1; // Let's do something better here!

  Particle(PVector l) {
    acceleration = new PVector(0,0);
    velocity = new PVector(random(-1,1),random(-2,0));
    location = l.get();
    lifespan = 255.0;
  }

  void run() {
    update();
    display();
  }

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

  // Method to update location
  void update() {
    velocity.add(acceleration);
    location.add(velocity);
    acceleration.mult(0);
    lifespan -= 2.0;
  }

  // Method to display
  void display() {
    stroke(0,lifespan);
    strokeWeight(2);
    fill(127,lifespan);
    ellipse(location.x,location.y,12,12);
  }

  // Is the particle still useful?
  boolean isDead() {
    if (lifespan < 0.0) {
      return true;
    } else {
      return false;
    }
  }
}
import java.util.Iterator;
class ParticleSystem {
  ArrayList<Particle> particles;
  PVector origin;

  ParticleSystem(PVector location) {
    origin = location.get();
    particles = new ArrayList<Particle>();
  }

  void addParticle() {
    particles.add(new Particle(origin));
  }

  // A function to apply a force to all Particles
  void applyForce(PVector f) {
    for (Particle p: particles) {
      p.applyForce(f);
    }
  }
**********关键部分*************
  void applyRepeller(Repeller r) {
    for (Particle p: particles) {
      PVector force = r.repel(p);        
      p.applyForce(force);
    }
  }


  void run() {
    Iterator<Particle> it = particles.iterator();
    while (it.hasNext()) {
      Particle p = it.next();
      p.run();
      if (p.isDead()) {
        it.remove();
      }
    }
  }
}

经过分析后发现,这种排斥力依然是通过力施加方法实现的,不过这里的力需要通过专门计算获得。也就是排斥物中的repel方法。这种实现非常巧妙的,避免了重复代码。

// Particles + Forces
// Daniel Shiffman <http://www.shiffman.net>

// A very basic Repeller class
class Repeller {
  
  // Gravitational Constant
  float G = 100;
  // Location
  PVector location;
  float r = 10;

  Repeller(float x, float y)  {
    location = new PVector(x,y);
  }

  void display() {
    stroke(0);
    strokeWeight(2);
    fill(175);
    ellipse(location.x,location.y,48,48);
  }

  // Calculate a force to push particle away from repeller
  PVector repel(Particle p) {
    PVector dir = PVector.sub(location,p.location);      // Calculate direction of force
    float d = dir.mag();                       // Distance between objects
    dir.normalize();                           // Normalize vector (distance doesn't matter here, we just want this vector for direction)
    d = constrain(d,5,100);                    // Keep distance within a reasonable range
    float force = -1 * G / (d * d);            // Repelling force is inversely proportional to distance
    dir.mult(force);                           // Get force vector --> magnitude * direction
    return dir;
  }  
}

具体来看repel函数,使用数学符号表示这一过程。
{\vec f=\vec r-\vec p \\ d=\Vert \vec f\Vert \\ \vec f_0=\vec f/\Vert \vec f\Vert \\d\in[5,100] \\\vec {force}=-1\cdot \frac{G}{d^2}\vec f_0 }
于是就获得了排斥力的表达形式,依然是距离的平方反比规律,不过方向掉转了。其中还有一个约束,限制了距离的最小和最大值,可能是一种截断函数。
{ d = \left\{ \begin{array}{ll} 100 & d\ge 100 \\ d & 5< d < 100\\ 5 & d \le 5 \end{array} \right. }

总结

不局限于此,可以考虑很多种形式的势场和势场所生成的力场,这个在量子力学的习题中见过不少,求给定势场下的粒子的波函数形式。
如果将一切都视为参数索引的物理量,那么还可以给出更多自由度,f(t,x,y,z),依赖于时间和位置的力函数,当然还有很多其他的实现,比如空间非平坦,那么距离的计算就需要考虑空间曲率。
动画就是时间依赖参数的更新与绘制,在每一帧中更新所需参数。

上一篇下一篇

猜你喜欢

热点阅读