• fullscreen
  • NLField.pde
  • NLParticles.pde
  • NLSystem.pde
  • SystemsOfEquations.pde
  • import processing.opengl.*;
    
    NonlinearSystem NLS;
    int curr_system = 1;
    float angle = 0;
    
    void setup() {
      size(900, 560, OPENGL);
      smooth(); 
      stroke(255, 40);  
      NLS = new NonlinearSystem(curr_system);
    }
    
    void draw() {
      background(0);
      lights();
      angle += PI/180;
      pushMatrix();  
      translate(width/2, height/2); 
      /* this next block of code was borrowed from 'Felix Woitzel'
       ** the code is used to control the angle of the camer
       ** source: http://www.openprocessing.org/visuals/?visualID=30490
       */
      //Begin borrowed code
      if (mouseY == 0)
        mouseY = 1;
      float w1 = (float) mouseX / (float) width * PI * 2;
      float w2 = (float) mouseY / (float) height * PI;    
      camera(width * cos(w1) * sin(w2), cos(w2) * width, width * sin(w1) * sin(w2), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
      //END borrowed code  
      rotateX(PI/7);  
      rotateY(PI/3);
      scale(0.9);  
      NLS.Render();
      popMatrix();  
      //if (frameCount % 300 == 0) saveFrame("rossler-####.jpg");
    }
    
    void keyPressed() {
      if (key == '1')
        curr_system = 0; 
      if (key == '2')
        curr_system = 1;      
      //disrupt the system and create the new system specified by the curr_system parameter
      NLS.Disrupt(curr_system);
    }
    
    
    class Particle {
      //this class holds the information for an individual particle within the particle system
      PVector pos, vel, accel, target;
      float error = 3;
      boolean found_target = false;
      
      Particle(){
        this.pos = new PVector(random(-width, width), random(-height, height), random(height));
        this.vel = new PVector(0, 0, 0);
        this.accel = new PVector(0, 0, 0);    
      }
      
      PVector Position(){
        //println(this.target.x + " " + this.target.y);
        return pos;
      }
      
      void Update(){
        //updates the position of the particle
        if (this.found_target == false){ 
          PVector dir = PVector.sub(target, pos);
          dir.normalize();
          this.AddForce(dir);
          this.vel.add(accel);
          this.vel.normalize();
          this.vel.mult(2);
          this.pos.add(vel);
          this.FoundTarget();
        }
        else
          this.Jitter();
      }
      
      void Jitter(){
        this.pos.x += random(-0.25, 0.25);      
        this.pos.y += random(-0.25, 0.25);  
        this.pos.z += random(-0.25, 0.25);      
      }
      
      void FoundTarget(){
        //if the particle is close enough to the target, then set the found target to true
        if (this.pos.x < this.target.x + this.error && this.pos.x > this.target.x - this.error){
          if (this.pos.y < this.target.y + this.error && this.pos.y > this.target.y - this.error){
          if (this.pos.z < this.target.z + this.error && this.pos.z > this.target.z - this.error)
            this.found_target = true;
          }
        }
      }
      
      void SetTarget(PVector target){
        this.found_target = false;
        this.target = new PVector(target.x, target.y, target.z);
      }
      
      void AddForce(PVector force){
        //adds a new force to the acceleratin of the particle
        this.accel.add(force);
      }
    }
    
    class NonlinearSystem {
      ArrayList parts = new ArrayList();
      int particles = 20000, iterations;
      //the field variable holds a reference to an equation system object
      //the calculate functino is called each time a new value is needed
      EQSystem field;
        
      NonlinearSystem(int system){
        this.iterations = this.particles;
        this.init(system);
      }  
        
      NonlinearSystem(int system, int particles){
        this.particles = particles;
        this.iterations = particles;    
        this.init(system);  
      }  
        
      void init(int system){
        if (system > 2 || system < 0)
          system = 0;
        field = new EQSystem(system);     
        AddParticle(new PVector(1.0, 0.0, 0.0));    
        //initialize the arraylist
        for (int i = 0; i < this.particles; i++){
          AddParticle(field.Generate());
        } 
      }  
      
      void Disrupt(int system){
        //this function alters the current position of each of the particles
        //essentially resetting them all toa new location
        this.field.Reset(system);
        this.parts = new ArrayList();
        for (int i = 0; i < this.particles; i++){
          AddParticle(field.Generate());
        }     
      }
      
      void AddParticle(PVector new_pos){
        Particle n = new Particle();
        n.SetTarget(new_pos);
        parts.add(n);    
      }
        
      void Render(){
        //update all the active particles and plot them
        Particle curr; 
        for (int i = 0; i < this.iterations; i++){
          curr = (Particle)this.parts.get(i);
          curr.Update();
          //PVector p = curr.Position();
          Plot(curr.Position());
        }
      }   
      
      void Plot(PVector pos){
        //draw the point as an ellipse on the screen    
        point(pos.x, pos.y, pos.z);
      }
    }
    
    class EQSystem {
      int system = 0;
      int LORENZ = 0, ROSSLER = 1;
      float dt = 0.01;
      PVector pt = new PVector(1.0, 0.0, 0.0);
     
      EQSystem(int system){
        this.system = system;
      } 
      
      EQSystem(int system, float dt){
        this.system = system;
        this.dt = dt;
      }
      
      void Reset(int system){
        //this function resest the internals of the system
        this.system = system;
        dt = 0.01;        
        pt = new PVector(1.0, 0.0, 0.0);   
      }
      
      PVector Generate(){
        PVector p = this.Calculate();
        float x = map(p.x, -15, 15, -1, 1);
        float y = map(p.y, -15, 15, -1, 1); 
        float z = map(p.z, -15, 15, -1, 1); 
        PVector s = new PVector(x, y, z);
        s.mult(width/3);
        return s;
      }
      
      PVector Calculate(){
         if (this.system == 0)
           return Lorenz(this.pt);
         else 
           return Rossler(this.pt);       
      }
      
      PVector Lorenz(PVector pos){
        float o = 15.0, p = 20.0, b = 9/3;  
        PVector dpos = new PVector(0, 0, 0);
        //println(pos.x + " " + pos.y + " " + pos.z);         
        dpos.x = o * (pos.y - pos.x);
        dpos.y = (pos.x * (p - pos.z)) - pos.y;
        dpos.z = (pos.x * pos.y) - (b * pos.z); 
        dpos.mult(this.dt);     
        //println("curr: " + dpos.x + " " + dpos.y + " " + dpos.z); 
        pos.add(dpos); 
        return pos;       
      }
      
      PVector Rossler(PVector pos){
        float a = 0.1, b = 0.1, c = 14;  
        PVector dpos = new PVector(0, 0, 0); 
        dpos.x = -pos.y - pos.z;
        dpos.y = pos.x + (a * pos.y);
        dpos.z = b + (pos.z * (pos.x - c)); 
        dpos.mult(this.dt);
        pos.add(dpos);   
        return pos;   
      }  
    }
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    This sketch is saved as a draft and it is not published on the homepage and browse page.

    license

    advertisement

    Ezekiel Kigbo

    Non-Linear Dynamic Systems (test)

    Add to Faves Me Likey@!
    You must login/register to add this sketch to your favorites.

    A sketch using particles to simulate a basic particle system, use the number '1' and '2' on your keyboard to reset the sketch and switch between a Rossler system and a Lorenz system.

    The system first randomly disperses the particles before each particle navigates to its target position, once the particle is close enough to its target location the particle starts to 'vibrate'.

    Code borrowed from 'Felix Woitzel' (http://www.openprocessing.org/visuals/?visualID=30490) for camera operations.

    Felix Woitzel
    7 Aug 2011
    nice one! you should use P3D instead of OpenGL for the web though.
    You need to login/register to comment.