OpenFrameworks boid demo

Nikolaus Gradwohl2010-08-19T04:42:45+02:00

I made a small boids demo in openframeworks. It is more or less a port of the boids demo i made in processing a while ago.

It's bin a while since i wrote c++ the last time, so i'm pretty sure i have forgotten to free some memory or have done something very unc++y :-)

of boids

The main class is just the standard openframeworks main from the emptyExample

main.cpp:

#include "ofMain.h"
#include "testApp.h"
#include "ofAppGlutWindow.h"

//========================================================================
int main( ){

    ofAppGlutWindow window;
    ofSetupOpenGL(&window, 1024,768, OF_WINDOW);            // <-------- setup the GL context

    // this kicks off the running of my app
    // can be OF_WINDOW or OF_FULLSCREEN
    // pass in width and height too:
    ofRunApp( new testApp());

}

in testApp.h i have defined an array of Boids

testApp.h:

#ifndef _TEST_APP
#define _TEST_APP


#include "ofMain.h"
#include "boid.h"

#define BOIDS 100

class testApp : public ofBaseApp{
    private:
        boid *boids[BOIDS];

    public:
        void setup();
        void update();
        void draw();

        void keyPressed  (int key);
};

#endif

in testApp.cpp i iterate over the array and update, and call the draw function of the individual boids

testApp.cpp:

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
    for( int i=0; i < BOIDS; i++) {
        boids[i] = new boid( ofRandom(0,ofGetWidth()), ofRandom(0,ofGetHeight()), ofRandom(-10,10), ofRandom(-10,10), boids, BOIDS );
    }
    ofSetFrameRate(25);
}

//--------------------------------------------------------------
void testApp::update(){
    for( int i=0; i < BOIDS; i++) {
        boids[i]->update();
    }

}

//--------------------------------------------------------------
void testApp::draw(){
    ofBackground(255,255,255);
    for( int i=0; i < BOIDS; i++) {
        boids[i]->draw();
    }
}

//--------------------------------------------------------------
void testApp::keyPressed(int key){
    for( int i=0; i < BOIDS; i++) {
        boids[i]->boo();
    }

}

In boids.h i define a class for the individual boids

boids.h:

#ifndef _BOID
#define _BOID

class boid {
    private:
      float r1;
      float r2;
      float r3;

      float x,y;
      float vx,vy;
      boid** others;
      int num_others;

    public:
        boid( float x, float y, float vx, float vy, boid* others[], int num_others );
        void boo();
        void update();
        void draw();

        void sep();
        void align();
        void coh();
};

#endif

and finally boids.cpp, this is where all the calculations happen

boids.cpp:

#include "boid.h"
#include "ofMain.h"
float sq( float a ) {
    return a * a;
}

boid::boid( float x, float y, float vx, float vy, boid* others[], int num_others ) {
    this->r1 = 40;
    this->r2 = 80;
    this->r3 = 160;

    this->x = x;
    this->y = y;
    this->vx = vx;
    this->vy = vy;
    this->others = others;
    this->num_others = num_others;
  }

void boid::boo() {
    vx = ofRandom( -25, 25 );
    vy = ofRandom( -25, 25 );
}

void boid::update() {
    sep();
    align();
    coh();

    float l = sqrt( sq( vx ) + sq ( vy ));
    if (l > 4 ) {
      vx = 0.9 * vx;
      vy = 0.9 * vy;
    }

    x += vx;
    y += vy;

    if (x > ofGetWidth() - 30 ) { vx -= 2; }
    if (x < 30 ) { vx += 2; }
    if (y > ofGetHeight() -30 ) {vy -= 2; }
    if (y < 30) { vy += 2; }
}

void boid::sep() {
    int count = 0;
    float sx = 0;
    float sy = 0;

    for ( int i = 0; i < num_others; i ++ ) {

      float d = sqrt( sq( x - others[i]->x ) + sq( y - others[i]->y ));
      if (d < r1 && this != others[i] ) {
        count++;
        sx += others[i]->x;
        sy += others[i]->y;
      }
    }

    if ( count  > 0 ){
      sx = x - sx / count;
      sy = y - sy / count;

      float l = sqrt( sq( sx ) + sq ( sy ));
      sx = 1.2 * sx / l;
      sy = 1.2 * sy / l;

    }

    vx += sx;
    vy += sy;
}

void boid::align() {
    int count = 0;
    float dx = 0;
    float dy = 0;

    for ( int i = 0; i < num_others; i ++ ) {

      float d = sqrt( sq( x - others[i]->x ) + sq( y - others[i]->y ));
      if (d < r2 && this != others[i] ) {
        count++;
        dx += others[i]->vx;
        dy += others[i]->vy;
      }
    }

    if ( count  > 0 ){
      dx = dx / count;
      dy = dy / count;
      float l = sqrt( sq( dx ) + sq ( dy ));
      dx = dx / l;
      dy = dy / l;
    }

    vx += dx;
    vy += dy;
  }

void boid::coh() {
    int count = 0;
    float sx = 0;
    float sy = 0;

    for ( int i = 0; i < num_others; i ++ ) {

      float d = sqrt( sq( x - others[i]->x ) + sq( y - others[i]->y ));
      if (d < r3  && d > r1 && this != others[i] ) {
        count++;
        sx += others[i]->x;
        sy += others[i]->y;
      }
    }

    if ( count  > 0 ){
      sx = x - sx / count;
      sy = y - sy / count;

      float l = sqrt( sq( sx ) + sq ( sy ));
      sx = sx / l;
      sy = sy / l;

    }

    vx -= sx;
    vy -= sy;
}


void boid::draw() {
    ofSetLineWidth(2);
    glPushMatrix();
        glTranslatef( x, y, 0 );
        float alpha = atan( vy/vx ) + ( vx < 0  ? PI : 0 );

        glRotatef( alpha * 180 / PI , 0,0,1);
        ofSetColor(228,228,228);
        ofFill();

        ofBeginShape();
            ofVertex( -15, -5 );
            ofVertex( -15, 5 );
            ofVertex( 15, 5 );
            ofVertex( 15, -5 );
        ofEndShape(true);
        ofSetColor(128,128,128);
        ofNoFill();

        ofBeginShape();
            ofVertex( -15, -5 );
            ofVertex( -15, 5 );
            ofVertex( 15, 5 );
            ofVertex( 15, -5 );
        ofEndShape(true);


    glPopMatrix();

}
Tweet This! submit to reddit Digg!   Tags: | 2 comments | no trackbacks

See also:

running openframeworks on a RaspberryPI
feeling watched in openframeworks
osc app using openframeworks
rotating box in openframeworks
OpenFrameworks Demo

Trackbacks

Comments

Leave a response

  1. Philo 2011-12-17T03:40:43+01:00

    Hi Nikolaus! Really nice projects! I had a go with your boid code and added some interactive capabilities for a course on openFrameworks. Please have a look! http://www.fromtimetoti.me/emergenes/

  2. delsotano 2013-01-16T12:58:09+01:00

    Hi Nikolaus!

    really cool;

    thanks for sharing!

Leave a comment