美文网首页
遗留的问题:排斥力如何实现

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

作者: Obj_Arr | 来源:发表于2022-07-01 20:01 被阅读0次

    原因

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

    代码

    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),依赖于时间和位置的力函数,当然还有很多其他的实现,比如空间非平坦,那么距离的计算就需要考虑空间曲率。
    动画就是时间依赖参数的更新与绘制,在每一帧中更新所需参数。

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/xwacbrtx.html