void DelaunayPulseOut::update( float elapsed ) { timer += elapsed; vector<pair< int, float > > pings; // update animation while ( !queued_pulses.empty() && queued_pulses.top().timer < timer ) { // fetch id int curr = queued_pulses.top().id; float energy = queued_pulses.top().energy; // remove from queue queued_pulses.pop(); // if we haven't already seen this one if ( seen.find( curr ) == seen.end() ) { // pulse the led lights->pulse( curr, energy ); // queue a ping pings.push_back( make_pair( curr, energy ) ); // add to seen seen.insert( curr ); // add neighbours to queue set<int> adj = lights->getDelaunay()->getNeighbours( curr ); // check neighbours against seen. ofxVec2f curr_pos( lights->getLight( curr ).getX(), lights->getLight( curr ).getY() ); for ( set<int>::iterator jt = adj.begin(); jt != adj.end(); ++jt ) { // add unseen neighbours if ( seen.find( *jt ) == seen.end() ) { ofxVec2f adj_pos( lights->getLight( *jt ).getX(), lights->getLight( *jt ).getY() ); float distance = ( adj_pos - curr_pos ).length(); queued_pulses.push( MovingPulse(*jt, energy*max(0.0f,1-falloff*distance), ofRandom(0.8f,1.2f)*(timer+(distance/speed)) ) ); } } } } // send pings for ( int i=0; i<pings.size(); i++ ) { ofxOscMessage m; m.setAddress( "/delaunay/ping" ); m.addFloatArg( pings[i].second ); const Light& light = lights->getLight( pings[i].first ); m.addFloatArg( light.getX() ); m.addFloatArg( light.getY() ); Osc::getInstance()->sendMessage( m ); } }
ActionType Simple::takeTurn(const Surroundings &s) const { // __posRandom takes in a vector of int (position) so make a vector of prioritized positions std::vector<int> potential_pos; // reset the position to the center of the grid. Position curr_pos(1, 1); Position new_pos; PositionRandomizer position; // look for food and loot first for (int i=0; i < 9; i++) { if (s.array[i] == FOOD || s.array[i] == ADVANTAGE) { potential_pos.push_back(i); } } if (potential_pos.size() > 0) { new_pos = Game::randomPosition(potential_pos); return Game::reachSurroundings(curr_pos, new_pos); } // look for somewhere safe to hide for (int i = 0; i < 9; i++) { if (s.array[i] == EMPTY) { potential_pos.push_back(i); } } if (potential_pos.size() > 0) { new_pos = Game::randomPosition(potential_pos); return Game::reachSurroundings(curr_pos, new_pos); } // if neither are available stay put return STAY; }
Point2D OpticalFlow::getAccumulatedDelta(const Point2D& position, const float32 radius, const clock_t timestamp) const { Point2D curr_pos(position); // Scale down to downsampled size. curr_pos.x /= downsample_factor_; curr_pos.y /= downsample_factor_; LOGV("Tracking accumulated delta from %.2f, %.2f", curr_pos.x, curr_pos.y); const float32 cutoff_dist = radius / downsample_factor_; // Anything that ended before the requested timestamp is of no concern to us. bool found_it = false; int32 num_frames_back = -1; for (int32 i = 0; i < num_frames_; ++i) { const FramePair& frame_pair = frame_pairs_[geNthIndexFromEnd(i)]; if (frame_pair.end_time <= timestamp) { num_frames_back = i - 1; if (num_frames_back > 0) { LOGV("Went %d out of %d frames before finding frame. (index: %d)", num_frames_back, num_frames_, geNthIndexFromEnd(i)); } found_it = true; break; } } if (!found_it) { const FramePair& frame_pair = frame_pairs_[geNthIndexFromStart(0)]; const FramePair& latest_frame_pair = frame_pairs_[geNthIndexFromEnd(0)]; clock_t latest_time = latest_frame_pair.end_time; LOGW("History did not go back far enough! %ld vs %ld", latest_time - frame_pair.end_time, latest_time - timestamp); } // Loop over all the frames in the queue, tracking the accumulated delta // of the point from frame to frame. It's possible the point could // go out of frame, but keep tracking as best we can, using points near // the edge of the screen where it went out of bounds. for (int32 i = num_frames_back; i >= 0; --i) { const FramePair& frame_pair = frame_pairs_[geNthIndexFromEnd(i)]; CHECK(frame_pair.end_time >= timestamp, "Frame timestamp was too early!"); const Point2D delta = frame_pair.queryFlow(curr_pos, cutoff_dist); curr_pos.x += delta.x; curr_pos.y += delta.y; } // Scale back to original size. curr_pos.x *= downsample_factor_; curr_pos.y *= downsample_factor_; // Return the delta only. return curr_pos - position; }
void DelaunayPulseIn::update( float elapsed ) { timer += elapsed; // update animation //printf("queue contains: "); vector<MovingPulse> dequeued; while ( !queued_pulses.empty() && queued_pulses.top().timer < timer ) { // dequeue dequeued.push_back( queued_pulses.top() ); // remove from queue queued_pulses.pop(); } // pings vector<pair< int, float > > pings; // coalesce pulses for the same node map<int,int> coalesced; for ( int i=0; i<dequeued.size(); i++ ) { int id = dequeued[i].id; // add ping here (because we might drop it later) pings.push_back( make_pair( id, dequeued[i].energy ) ); // coalesce if ( coalesced.find( id ) == coalesced.end() ) { coalesced[id] = i; } else { // merge dequeued[coalesced[id]].energy += dequeued[i].energy; // remove dequeued.erase( dequeued.begin()+i ); i--; } } // no go through coalesced for ( int i=0; i<dequeued.size(); i++ ) { // fetch id int curr = dequeued[i].id; float energy = dequeued[i].energy; //printf("%2i:%7.5f ", curr, energy ); // pulse the led if ( dequeued[i].timer > 0 ) lights->pulse( curr, energy ); // finished? if ( curr == target_index || energy < 0.001f ) continue; // add the closest neighbours to queue set<int> adj = delaunay->getNeighbours( curr ); ofxVec2f curr_pos( lights->getLight( curr ).getX(), lights->getLight( curr ).getY() ); ofxVec2f target_pos( lights->getLight( target_index ).getX(), lights->getLight( target_index ).getY() ); // use for calculating dot product (-> angle ) ofxVec2f target_delta = target_pos - curr_pos; float distance_to_target = target_delta.length(); target_delta /= distance_to_target; //printf("delta to target is %7.5f %7.5f\n", target_delta.x, target_delta.y ); for ( set<int>::iterator jt = adj.begin(); jt != adj.end(); ++jt ) { // add neighbours, distributing energy ofxVec2f adj_pos( lights->getLight( *jt ).getX(), lights->getLight( *jt ).getY() ); ofxVec2f adj_delta = adj_pos - curr_pos; float distance = adj_delta.length(); adj_delta /= distance; // dot product float direction_accuracy = target_delta.dot( adj_delta ); // would this path take us towards the target? //printf(" adj delta to next is %7.5f %f7.5 -> accuracy %7.5f\n", adj_delta.x, adj_delta.y, direction_accuracy ); if ( direction_accuracy > 0.5f ) { direction_accuracy*=direction_accuracy; // yes //float new_energy = direction_accuracy*0.5f*(max_brightness*(1.0f-(distance_to_target/initial_radius))); float falloff = 0.25f; float new_energy = energy*direction_accuracy*0.5f - energy*distance*falloff; queued_pulses.push( MovingPulse(*jt, new_energy, ofRandom(0.8f,1.2f)*(timer+(distance/speed)) ) ); } } } //printf("\n"); // send pings for ( int i=0; i<pings.size(); i++ ) { ofxOscMessage m; m.setAddress( "/delaunay/ping" ); m.addFloatArg( pings[i].second ); const Light& light = lights->getLight( pings[i].first ); m.addFloatArg( light.getX() ); m.addFloatArg( light.getY() ); m.addFloatArg( delaunay->getId() ); Osc::getInstance()->sendMessage( m ); } }