Created
March 20, 2012 22:11
-
-
Save roxlu/2141784 to your computer and use it in GitHub Desktop.
Poor mans Hyphae growth
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "rxParticle.h" | |
rxParticle::rxParticle(ofVec3f pos, float mass) | |
:position(pos) | |
,mass(mass) | |
,velocity(0) | |
,forces(0) | |
,age(0) | |
,lifetime(10) | |
{ | |
if(mass < 0.001) { | |
mass = 0.001; | |
} | |
inv_mass = 1.0/mass; | |
} | |
rxParticle::~rxParticle() { | |
printf("~rxParticle, lifetime: %f\n", lifetime); | |
} | |
void rxParticle::update() { | |
forces *= inv_mass; | |
velocity += forces; | |
position += velocity; | |
velocity *= 0.98f; | |
forces.set(0,0,0); | |
} | |
void rxParticle::draw() { | |
glVertex3fv(&position.x); | |
} | |
void rxParticle::reset() { | |
neighbors.clear(); | |
//age = 0; | |
lifetime = 10; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef ROXLU_RXPARTICLEH | |
#define ROXLU_RXPARTICLEH | |
#include "ofMain.h" | |
class rxParticle { | |
public: | |
rxParticle(ofVec3f position, float mass); | |
~rxParticle(); | |
void update(); | |
void draw(); | |
void reset(); | |
float mass; | |
float inv_mass; | |
float age; | |
float lifetime; | |
ofVec3f forces; | |
ofVec3f velocity; | |
ofVec3f position; | |
vector<rxParticle*> neighbors; | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "rxParticles.h" | |
rxParticles::rxParticles() { | |
} | |
rxParticles::~rxParticles() { | |
} | |
void rxParticles::update() { | |
list<rxParticle*>::iterator it = particles.begin(); | |
while(it != particles.end()) { | |
(*it)->update(); | |
++it; | |
} | |
list<rxSpring*>::iterator its = springs.begin(); | |
while(its != springs.end()) { | |
(*its)->update(); | |
++its; | |
} | |
} | |
void rxParticles::draw() { | |
glColor3f(0,0,0); | |
// glBegin(GL_TRIANGLES); | |
glBegin(GL_LINES); | |
list<rxSpring*>::iterator its = springs.begin(); | |
while(its != springs.end()) { | |
(*its)->draw(); | |
++its; | |
} | |
glEnd(); | |
glPointSize(8); | |
glColor3f(0,0,0); | |
glBegin(GL_POINTS); | |
list<rxParticle*>::iterator it = particles.begin(); | |
while(it != particles.end()) { | |
(*it)->draw(); | |
++it; | |
} | |
glEnd(); | |
glColor3f(1,1,1); | |
} | |
void rxParticles::addParticle(rxParticle* p) { | |
particles.push_back(p); | |
} | |
// only remove, no delete | |
void rxParticles::removeParticle(rxParticle* p) { | |
list<rxParticle*>::iterator it = std::find(particles.begin(), particles.end(), p); | |
if(it != particles.end()) { | |
particles.erase(it); | |
} | |
} | |
void rxParticles::addSpring(rxSpring* s) { | |
springs.push_back(s); | |
} | |
void rxParticles::addSwirp(rxSwirp* s) { | |
swirps.push_back(s); | |
} | |
void rxParticles::addForce(const ofVec3f& f) { | |
list<rxParticle*>::iterator it = particles.begin(); | |
while(it != particles.end()) { | |
(*it)->forces += f; | |
++it; | |
} | |
} | |
void rxParticles::follow(const ofVec3f& f, float effect) { | |
list<rxParticle*>::iterator it = particles.begin(); | |
ofVec3f dir; | |
float force; | |
float length; | |
while(it != particles.end()) { | |
rxParticle& p = *(*it); | |
dir = f - p.position; | |
length = dir.length(); | |
dir.normalize(); | |
dir *= length * effect; | |
(*it)->forces += dir; | |
++it; | |
} | |
} | |
void rxParticles::repel(float effect) { | |
ofVec3f dir; | |
float f; | |
float length_sq; | |
int now = ofGetElapsedTimeMillis(); | |
list<rxParticle*>::iterator ita = particles.begin(); | |
list<rxParticle*>::iterator itb = particles.begin(); | |
while(ita != particles.end()) { | |
itb = ita; | |
++itb; | |
rxParticle& a = *(*ita); | |
while(itb != particles.end()) { | |
rxParticle& b = *(*itb); | |
dir = b.position - a.position; | |
length_sq = dir.lengthSquared(); | |
if(length_sq > 0.0f) { | |
f = 1.0f/length_sq; | |
dir *= (f * effect); | |
a.forces -= dir; | |
b.forces += dir; | |
} | |
++itb; | |
} | |
++ita; | |
} | |
int end = ofGetElapsedTimeMillis(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef ROXLU_RXPARTICLESH | |
#define ROXLU_RXPARTICLESH | |
#include "ofMain.h" | |
#include "rxParticle.h" | |
#include "rxSpring.h" | |
#include "rxSwirp.h" | |
#include <list> | |
using std::list; | |
class rxParticles { | |
public: | |
rxParticles(); | |
~rxParticles(); | |
void draw(); | |
void update(); | |
void repel(float effect = 0.3); | |
void follow(const ofVec3f& pos, float effect = 0.001f); | |
void addForce(const ofVec3f& f); | |
void addParticle(rxParticle* p); | |
void removeParticle(rxParticle* p); | |
void addSpring(rxSpring* s); | |
void addSwirp(rxSwirp* s); | |
list<rxParticle*> particles; | |
list<rxSpring*> springs; | |
list<rxSwirp*> swirps; | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "rxVeins.h" | |
rxVeins::rxVeins() { | |
} | |
rxVeins::~rxVeins() { | |
} | |
void rxVeins::addSource(rxParticle* p) { | |
sources.push_back(p); | |
sources_ps.addParticle(p); | |
} | |
void rxVeins::addRoot(rxParticle* p) { | |
roots.push_back(p); | |
} | |
void rxVeins::step() { | |
printf("Num sources: %zu, num roots: %zu\n", sources.size(), roots.size()); | |
vector<rxParticle*>::iterator sit = sources.begin(); | |
vector<rxParticle*>::iterator rit = roots.begin(); | |
sources_to_nodes.clear(); | |
while(rit != roots.end()) { | |
(*rit)->reset(); | |
++rit; | |
} | |
// for each source search the particles which is closest auxin sources. | |
ofVec3f dir(0,0,0); | |
float length_sq = 0.0; | |
while(sit != sources.end()) { | |
rxParticle& source = *(*sit); | |
// do we need to remove this auxin source? | |
if(source.lifetime < 0) { | |
sources_ps.removeParticle(*sit); | |
delete *sit; | |
sit = sources.erase(sit); | |
continue; | |
} | |
// find the closest root for this source | |
rit = roots.begin(); | |
float closest_dist = FLT_MAX; | |
rxParticle* closest_node = NULL; | |
while(rit != roots.end()) { | |
rxParticle& root = *(*rit); | |
dir = root.position - source.position; | |
length_sq = dir.lengthSquared(); | |
if(length_sq < closest_dist) { | |
closest_dist = length_sq; | |
closest_node = *rit; | |
} | |
++rit; | |
} | |
if(closest_node != NULL) { | |
closest_node->lifetime = 5; | |
sources_to_nodes[*sit].push_back(closest_node); | |
closest_node->neighbors.push_back(*sit); | |
} | |
++sit; | |
} | |
// move roots towards auxin sources. | |
float min_dist = 2; | |
float min_dist_sq = min_dist*min_dist; | |
float dist_sq = 0; | |
float num_sources = 0.0f; | |
float D = 3; | |
ofVec3f average(0,0,0); | |
rit = roots.begin(); | |
vector<rxParticle*> new_roots; | |
while(rit != roots.end()) { | |
rxParticle& root = *(*rit); | |
if(root.lifetime != 5) { | |
delete *rit; | |
rit = roots.erase(rit); | |
// ++rit; | |
continue; | |
} | |
average.set(0,0,0); | |
num_sources = 0; | |
vector<rxParticle*>::iterator nit = root.neighbors.begin(); | |
while(nit != root.neighbors.end()) { | |
dir = (*nit)->position - root.position; | |
dist_sq = dir.lengthSquared(); | |
average += dir; | |
num_sources++; | |
// mark for deletion. | |
if(dist_sq < min_dist_sq) { | |
(*nit)->lifetime = -1; | |
} | |
++nit; | |
} | |
average /= num_sources; | |
average.normalize(); | |
average *= D; | |
average += root.position; | |
rxParticle* new_root = new rxParticle(average, 0); | |
new_roots.push_back(new_root); | |
nodes.push_back(average); | |
++rit; | |
} | |
for(int i = 0; i < new_roots.size(); ++i) { | |
addRoot(new_roots[i]); | |
} | |
} | |
void rxVeins::draw() { | |
vector<rxParticle*>::iterator it = sources.begin(); | |
while(it != sources.end()) { | |
rxParticle& p = *(*it); | |
glColor3f(1,1,1); | |
ofCircle(p.position.x, p.position.y, 3); | |
glColor3f(0.22,0.33,0.44); | |
ofCircle(p.position.x, p.position.y, 2); | |
++it; | |
} | |
glColor3f(0,1,1); | |
vector<rxParticle*>::iterator rit = roots.begin(); | |
while(rit != roots.end()) { | |
rxParticle& p = *(*rit); | |
glColor3f(1,1,1); | |
ofCircle(p.position.x, p.position.y, 2); | |
glColor3f(1,0.0,0.0); | |
ofCircle(p.position.x, p.position.y, 1); | |
++rit; | |
} | |
glColor3f(1,1,1); | |
glBegin(GL_POINTS); | |
vector<ofVec3f>::iterator nit = nodes.begin(); | |
while(nit != nodes.end()) { | |
glVertex3fv(&nit->x); | |
//ofCircle(nit->x, nit->y, 3); | |
++nit; | |
} | |
glEnd(); | |
glBegin(GL_LINES); | |
map<rxParticle*, list<rxParticle*> >::iterator mit = sources_to_nodes.begin(); | |
while(mit != sources_to_nodes.end()) { | |
glColor3f(1,0,0); | |
rxParticle& a = *(mit->first); | |
glVertex3fv(&a.position.x); | |
list<rxParticle*>::iterator lt = mit->second.begin(); | |
while(lt != mit->second.end()) { | |
rxParticle& b = *(*lt); | |
glColor3f(1,1,1); | |
glVertex3fv(&b.position.x); | |
++lt; | |
} | |
++mit; | |
} | |
glEnd(); | |
} | |
void rxVeins::update() { | |
sources_ps.repel(0.1); | |
sources_ps.update(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef ROXLU_VEINSH | |
#define ROXLU_VEINSH | |
#include "ofMain.h" | |
#include "rxParticle.h" | |
#include "rxParticles.h" | |
#include <list> | |
class rxVeins { | |
public: | |
rxVeins(); | |
~rxVeins(); | |
void addSource(rxParticle* s); | |
void addRoot(rxParticle* r); | |
void step(); | |
void update(); | |
void draw(); | |
rxParticles sources_ps; | |
vector<rxParticle*> sources; | |
vector<rxParticle*> roots; | |
vector<ofVec3f> nodes; | |
map<rxParticle*, list<rxParticle*> > sources_to_nodes; | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
WORK IN PROGRESS, NOT CORRECT, WITH BUGS