void Boid::intersects(ofxCvContourFinder& _cv, Path* _path){ ofPoint heading = loc + vel*30; // A vector pointing from the location to where the boid is heading for ( int i = 0; i < _cv.blobs.size(); i++ ) { ofxCvBlob temp = _cv.blobs[i]; ofPolyline l; l.addVertexes(temp.pts); if(l.inside(heading)) { counter = 0; avoidObject = true; ofPoint force = heading - _cv.blobs[i].centroid; ofPoint force2 = getNormalPoint(force, heading, _cv.blobs[i].centroid); acc += force.normalize()* 1.5; cout << "bounce!\n"; } else { avoidObject = false; counter++; } } if ( counter > 400 && avoidObject == false) { follow(_path); } }
ofPoint SuperGlyph::getGetClosePath(ofPoint _pos){ ofPoint normal; ofPoint target; float minDist = 1000000; for (int i = 0; i < insidePath.getVertices().size()-1; i++) { ofPoint a = insidePath.getVertices()[i]; ofPoint b = insidePath.getVertices()[i+1]; ofPoint normalPoint = getNormalPoint(_pos, a, b); if (normalPoint.x < a.x || normalPoint.x > b.x) { normalPoint = b; } float distance = _pos.distance(normalPoint); if (distance < minDist) { minDist = distance; normal = normalPoint; ofPoint dir = b - a; dir.normalize(); dir *= 10; target = normalPoint; target += dir; } } return target; }
void Boid::follow(Path* p) { ofPoint predict = vel; Path::normalize(&predict); predict *= 30; predictLoc = loc + predict; // Now we must find the normal to the path from the predicted location // We look at the normal for each line segment and pick out the closest one record = 1000000; // Start with a very high record distance that can easily be beaten // Loop through all points of the path for (int i = 0; i < p->points.size()-1; i++) { // Look at a line segment ofPoint a = p->points[i]; ofPoint b = p->points[i+1]; // Get the normal point to that line ofPoint normal = getNormalPoint(predictLoc,a,b); // Check if normal is on line segment float da = ofDist(normal.x, normal.y, a.x, a.y); float db = ofDist(normal.x, normal.y, b.x, b.y); ofPoint line = b-a; // If it's not within the line segment, consider the normal to just be the end of the line segment (point b) if (da + db > Path::mag(&line)+1.0) { normal = b; } // How far away are we from the path? float d = ofDist(predictLoc.x, predictLoc.y, normal.x, normal.y); // Did we beat the record and find the closest line segment? if (d < record) { record = d; // If so the target we want to steer towards is the normal target = normal; // Look at the direction of the line segment so we can seek a little bit ahead of the normal dir = line; Path::normalize(&dir); // This is an oversimplification // Should be based on distance to path & velocity dir*=5; } } // Steer if the record object is even slightly off the center of the path if (record > 1) { target += dir; seek(target); } }
void Vehicle::follow(Path path) { ofVec2f predict = velocity.getNormalized(); predict *= 25; predictLoc = location + predict; ofVec2f a = path.getStartPoint(); ofVec2f b = path.getEndPoint(); normalPoint = getNormalPoint(predictLoc, a, b); ofVec2f dir = b - a; dir.normalize(); dir *= 10; target = normalPoint + dir; float distance = normalPoint.distance(predictLoc); seeking = (distance > path.getRadius()); if(seeking) seek(target); }
void Vehicle::follow(Path & p){ radius = p.radius; // Predict location 25 (arbitrary choice) frames ahead ofVec2f predict(velocity); predict.normalize(); predict *= 25; predictLoc = location + predict; worldRecord = 1000000; // Loop through all points of the path for (unsigned int i = 0; i < p.points.size()-1; i++) { // Look at a line segment ofVec2f a(p.points[i]); ofVec2f b(p.points[i+1]); // Get the normal point to that line ofVec2f normalPoint = getNormalPoint(predictLoc, a, b); if (normalPoint.x <= a.x || normalPoint.x >= b.x) { // This is something of a hacky solution, but if it's not within the line segment // consider the normal to just be the end of the line segment (point b) normalPoint.set(b.x, b.y); } // How far away are we from the path? float distance = ofDist(predictLoc.x, predictLoc.y, normalPoint.x, normalPoint.y); if (distance < worldRecord) { worldRecord = distance; normal = normalPoint; ofVec2f dir = b - a; dir.normalize(); dir *= 10; // This could be based on velocity instead of just an arbitrary 10 pixels target.set(normalPoint); target += dir; } } if (worldRecord > p.radius) { seek(target); } cout << target.x << endl; }
ofxVec2f Boid :: follow( const Path& path ) { predict.set( 0, 0 ); // reset. predict.set( vel ); predict.normalize(); predict *= 25; predictLoc.set( 0, 0 ); // reset. predictLoc = loc + predict; target.set( 0, 0 ); // reset. float record = 1000000; for( int i=0; i<path.points.size(); i++ ) { ofxVec2f a; a.set( path.points.at( i ) ); // current point. ofxVec2f b; b.set( path.points.at( ( i + 1 ) % path.points.size() ) ); // next point. // the normal is a vector that extends from that point and is perpendicular to the line. // http://www.shiffman.net/itp/classes/nature/pathimages/path5normal.jpg // http://www.shiffman.net/itp/classes/nature/pathimages/path6normal.jpg ofxVec2f normal; normal = getNormalPoint( predictLoc, a, b ); // check if normal is on line segment float da; da = normal.distance( a ); float db; db = normal.distance( b ); ofxVec2f line; line = b - a; // if it's not within the line segment, consider the normal to just be the end of the line segment (point b) if( da + db > line.length() + 1 ) { normal.set( b ); a.set( path.points.at( ( i + 1 ) % path.points.size() ) ); b.set( path.points.at( ( i + 2 ) % path.points.size() ) ); line = b - a; } float d; d = predictLoc.distance( normal ); if( d < record ) { record = d; target.set( normal ); dir.set( line ); dir.normalize(); dir *= 25; } } if( record > path.radius || vel.length() < 0.1 ) { target += dir; return steer( target, false ); } else { ofxVec2f v; return v; } }