• fullscreen
  • SteeredVehicle.pde
  • Vector2D.pde
  • Vehicle.pde
  • steering09FlockingFish.pde
  • class SteeredVehicle extends Vehicle
    {
      // _maxForce best values
      // seek 0.05 - 0.1, flee 0.01 - 0.05
      float _maxForce = 0.1; //1.0;
      Vector2D _steeringForce;
      
      float _arrivalThreshold = 100;
      
      float _wanderAngle = 0.0; //0
      float _wanderDistance = 10.0; //10
      float _wanderRadius = 5.0; //5
      float _wanderRange = 1.0; //1
      
      float _avoidDistance = 50;
      float _avoidBuffer = 10;
      
      int _pathIndex = 0;
      float _pathThreshold = 20;
      Boolean _loopRound = false;
      
      float _inSightDist = 200;
      float _tooCloseDist = 60;
      
      
      SteeredVehicle()
      {
        super();
        _steeringForce = new Vector2D();
      }
      
      SteeredVehicle(Vector2D _position, Vector2D _velocity)
      {
        super(_position, _velocity);
        _steeringForce = new Vector2D();
      }
    
      // set/get maxForce
      void setMaxForce(float value)
      {
        _maxForce = value;
      }
      float getMaxForce()
      {
        return _maxForce;
      }
      
      void update()
      {
        _steeringForce.limit(_maxForce);
        _steeringForce.div(_mass);
        _velocity.add(_steeringForce);
        _steeringForce = new Vector2D();
    //          if (_position.x < 0 ) exit();
        super.update();
      }
      
      //*** seek and flee
      // differ only by addition or subtraction of force
      void seek(Vector2D target)
      {
        Vector2D desiredVelocity = target.clone();
        desiredVelocity.sub(_position);
        desiredVelocity.normalize();
        desiredVelocity.mult(_maxSpeed);
        Vector2D force = desiredVelocity.clone();
        force.sub(_velocity);
        _steeringForce.add(force);
      }
      void flee(Vector2D target)
      {
        Vector2D desiredVelocity = target.clone();
        desiredVelocity.sub(_position);
        desiredVelocity.normalize();
        desiredVelocity.mult(_maxSpeed);
        Vector2D force = desiredVelocity.clone();
        force.sub(_velocity);
        _steeringForce.sub(force);
      }
    
      //*** arrive
      void arrive(Vector2D target)
      {
        Vector2D desiredVelocity = target.clone();
        desiredVelocity.sub(_position);
        desiredVelocity.normalize();
        float distV = _position.distV(target);
        if(distV > _arrivalThreshold)
        {
          desiredVelocity.mult(_maxSpeed);
        }
        else
        {
          desiredVelocity.mult(_maxSpeed * distV / _arrivalThreshold);
        }
        
        Vector2D force = desiredVelocity.clone();
        force.sub(_velocity);
        _steeringForce.add(force);
      }
      
      //*** persue and evade
      void persue(Vehicle target)
      {
        float lookAheadTime = _position.distV(target._position) / _maxSpeed;
        Vector2D predictedPosition = target._position.clone();
        Vector2D predictedVelocity = target._velocity.clone();
        predictedVelocity.mult(lookAheadTime);
        predictedPosition.add(predictedVelocity);
        seek(predictedPosition);
      }
      void evade(Vehicle target)
      {
        float lookAheadTime = _position.distV(target._position) / _maxSpeed;
        Vector2D predictedPosition = target._position.clone();
        Vector2D predictedVelocity = target._velocity.clone();
        predictedVelocity.mult(lookAheadTime);
        predictedPosition.sub(predictedVelocity);
        flee(predictedPosition);
      }
    
      //*** wander
      void wander()
      {
        Vector2D centre = _velocity.clone();
        centre.normalize();
        centre.mult(_wanderDistance);
        Vector2D offset = new Vector2D(0,0);
        offset.setLength(_wanderRadius);
        offset.setAngle(_wanderAngle);
        _wanderAngle += random(-_wanderRange, _wanderRange);
        Vector2D force = centre.clone();
        force.add(offset);
        _steeringForce.add(force);
      }
    
      
      //*** flocking
      void flock(Vehicle[]Vehicles)
      {
        Vector2D averageVelocity = _velocity.clone();
        Vector2D averagePosition = new Vector2D();
        int inSightCount = 0;
        for(int v = 0; v < Vehicles.length; v++)
        {
          if(Vehicles[v] != this && inSight(Vehicles[v]))
          {
            averageVelocity.add(Vehicles[v]._velocity);
            averagePosition.add(Vehicles[v]._position);
            if(tooClose(Vehicles[v])) flee(Vehicles[v]._position);
            inSightCount++;
          }
        }
        
        if(inSightCount > 0)
        {
          averageVelocity.div(inSightCount);
          averagePosition.div(inSightCount);
          seek(averagePosition);
          averageVelocity.sub(_velocity);
          _steeringForce.add(averageVelocity);
        }
        
      }
      Boolean inSight(Vehicle vehicle)
      {
        if(_position.distV(vehicle._position) > _inSightDist) return false;
        Vector2D heading = _velocity.clone();
        heading.normalize();
        Vector2D difference = vehicle._position.clone();
        difference.sub(_position);
        float dotProd = difference.dot(heading);
        if(dotProd < 0) return false;
        
        return true;
      }
      Boolean tooClose(Vehicle vehicle)
      {
        return _position.distV(vehicle._position) < _tooCloseDist;
      }
      void setInSightDist(float value)
      {
        _inSightDist = value;
      }
      float getInSightDist()
      {
        return _inSightDist;
      }
      void setTooCloseDist(float value)
      {
        _tooCloseDist = value;
      }
      float getTooCloseDist()
      {
        return _tooCloseDist;
      }
    }
    
    class Vector2D extends PVector
    {
      Vector2D()
      {
      }
     
      Vector2D(float x, float y)
      {
        super(x, y);
      }
    
      
      Vector2D clone()
      {
        return new Vector2D(x, y);
      }
      
      //*** zero and isZero
      Vector2D zero()
      {
        x = 0;
        y = 0;
        return this;
      }
      Boolean isZero()
      {
        return x == 0 && y == 0;
      }
      
      //*** sets/gets length
      void setLength(float someLength)
      {
        float a = getAngle();
        x = cos(a) * someLength;
        y = sin(a) * someLength;
      }
      float getLength()
      {
        return sqrt(x*x + y*y);
      }
      
      //*** sets/gets angle
      void setAngle(float someAngle)
      {
        float len = getLength();
        x = cos(someAngle) * len;
        y = sin(someAngle) * len;
      }
      float getAngle()
      {
        return atan2(y, x);
      }
      
      //*** nomalise and isNormalised
      // normalise = PVector.normalize()
      Boolean isNormalised()
      {
        float diff = getLength() - 1.0;
        if ((diff < 0.00001) && (diff >= 0.0)) return true;
        if ((diff > - 0.00001) && (diff <= 0.0)) return true;
        return false;
      }
      
      //*** sign
      //is second vector to the right (+1) or left (-1)
      //of current vector
      int sign(Vector2D v2)
      {
        return perp().dot(v2) < 0 ? -1 : 1;
      }
      
      
      //*** perpendicular vector
      Vector2D perp()
      {
        return new Vector2D(-y, x);
      }
      
      //*** isEqual
      Boolean equal(Vector2D v2)
      {
        return (x == v2.x) && (y == v2.y);
      }
      
      //*** distance to second vector2d
      float distV(Vector2D v2)
      {
        float dx = x - v2.x;
        float dy = y - v2.y;
        return sqrt(dx*dx + dy*dy);
      }
    }
    
    class Vehicle
    {
      Vector2D _position;
      Vector2D _velocity;
      float _x, _y, _rotation;
      
      float _maxSpeed = 2;
      float _mass = 1.0;
      float _bounce = -1;
      
      String WRAP = new String("wrap");
      String BOUNCE = new String("bounce");
      String _edgeBehaviour = BOUNCE;  
      
      Vehicle()
      {
      }
      
      
      Vehicle(Vector2D _position, Vector2D _velocity)
      {
        this._position = _position;
        this._velocity = _velocity;
      }
      
      void update()
      {
        _velocity.limit(_maxSpeed);
        _position.add(_velocity);
    
        if(_edgeBehaviour.equals(WRAP)) wrapWalls();
        else if(_edgeBehaviour.equals(BOUNCE)) bounceWalls();
    
        display();
      }
      
      void display()
      {
    //    stroke(255);
        noStroke();
        pushMatrix();
        translate(_position.x, _position.y);
        rotate(_velocity.getAngle()); 
        fill(255, 120, 0);
        ellipse(0, 0, 20, 10);
        beginShape(TRIANGLES);
        vertex(5, 0);
        vertex(-5, 10);
        vertex(-5, -10);
        endShape();
        beginShape(TRIANGLES);
        vertex(-5, 0);
        vertex(-15, 5);
        vertex(-15, -5);
        endShape();
        fill(0);
        ellipse(5, 0, 3, 3);
        popMatrix();
      }
      
      // set/get edgeBehaviour wrap or bounce
      void setEdgeBehaviour(String value)
      {
        _edgeBehaviour = value;
      }
      String getEdgeBehaviour()
      {
        return _edgeBehaviour;
      }  
      
      void wrapWalls()
      {
        if(_position.x > width)  _position.x = 0;
        else if(_position.x < 0) _position.x = width;
        if(_position.y > height) _position.y = 0;
        else if(_position.y < 0) _position.y = height;
      }
      
      void bounceWalls()
      {
        if(_position.x > width)
        {
          _position.x = width;
          _velocity.x *= _bounce;
        }
        else if(_position.x < 0)
        {
          _position.x = 0;
          _velocity.x *= _bounce;
        }
        if(_position.y > height)
        {
          _position.y = height;
          _velocity.y *= _bounce;
        }
        else if(_position.y < 0)
        {
          _position.y = 0;
          _velocity.y *= _bounce;
        }
      }
    }
    
    // steering behaviour
    // Keith Peters - Advanced ActionScript Animation
    // converted to processing - allonestring Jan 2010
    // converted to fish August 2011
    
    int numVehicles = 37;
    SteeredVehicle[]Vehicles = new SteeredVehicle[numVehicles];
    
    
    void setup()
    {
      size(800, 500);
      
      for(int v = 0; v < numVehicles; v++)
      {
        Vector2D startPosition = new Vector2D(random(width), random(height));
        Vector2D startVelocity = new Vector2D(random(-2, 2), random(-2, 2));
        Vehicles[v] = new SteeredVehicle(startPosition, startVelocity);
      }
    }
    
    
    void draw()
    {
      background(0, 16, 64);
      
      for(int v = 0; v < numVehicles; v++)
      {
        
        Vehicles[v].flock(Vehicles);
        Vehicles[v].setEdgeBehaviour("wrap");
        Vehicles[v].update();
      }
    }
    
    
    

    code

    tweaks (0)

    about this sketch

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

    license

    advertisement

    allonestring

    flocking fish

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

    I don't know why they stop and squabble now and then - perhaps I should pretend that it's deliberate.

    ananta ghimire
    18 Dec 2011
    cannot find class name or type name vehicle when i copy in my processing .please say me about this
    You need to login/register to comment.