/*! */ bool Bhv_Hunt::execute( PlayerAgent * agent ) { std::list<Vector2D> forces; //Get force from prey Vector2D preyForce = agent->world().ball().rpos(); //Vector to prey int preyCo = 1; // for future usee forces.push_front(preyForce * preyCo/preyForce.r2()); //1/r^2 relationship // Get forces from team mates // PlayerCont * team = agent->world().teammates(); // for ( PlayerCont::const_iterator tm = team.begin(); tm != team.end(); ++tm ){ // } //Sum up all forces to create resultant vector Vector2D * resultant = new Vector2D(); for ( std::list<Vector2D>::iterator it = forces.begin(); it != forces.end(); ++it ){ *resultant = *resultant + *it; } if ( Body_GoToPoint (*resultant, 5, resultant->r()).execute( agent ) ){ agent->setNeckAction( new Neck_TurnToBall()); return true; } return false; }
/*! */ Vector2D Segment2D::nearestPoint( const Vector2D & p ) const { const Vector2D vec = terminal() - origin(); const double len_square = vec.r2(); if ( len_square == 0.0 ) { return origin(); } double inner_product = vec.innerProduct( (p - origin()) ); // // A: p1 - p0 // B: p - p0 // // check if 0 <= |B|cos(theta) <= |A| // -> 0 <= |A||B|cos(theta) <= |A|^2 // -> 0 <= A.B <= |A|^2 // A.B = |A||B|cos(theta) // if ( inner_product <= 0.0 ) { return origin(); } else if ( inner_product >= len_square ) { return terminal(); } return origin() + vec * inner_product / len_square; }
/*! */ void InterceptTable::createBallCache() { const ServerParam & SP = ServerParam::i(); const double pitch_x_max = ( SP.keepawayMode() ? SP.keepawayLength() * 0.5 : SP.pitchHalfLength() + 5.0 ); const double pitch_y_max = ( SP.keepawayMode() ? SP.keepawayWidth() * 0.5 : SP.pitchHalfWidth() + 5.0 ); const double bdecay = SP.ballDecay(); Vector2D bpos = M_world.ball().pos(); Vector2D bvel = M_world.ball().vel(); M_ball_pos_cache.push_back( bpos ); if ( M_world.self().isKickable() ) { return; } for ( std::size_t i = 1; i <= MAX_CYCLE; ++i ) { bpos += bvel; bvel *= bdecay; M_ball_pos_cache.push_back( bpos ); if ( i >= 5 && bvel.r2() < 0.01*0.01 ) { // ball stopped break; } if ( bpos.absX() > pitch_x_max || bpos.absY() > pitch_y_max ) { // out of pitch break; } } if ( M_ball_pos_cache.size() == 1 ) { M_ball_pos_cache.push_back( bpos ); } }
/*! */ void PlayerObject::updateBySee( const SideID side, const Localization::PlayerT & p ) { M_side = side; M_ghost_count = 0; // unum is updated only when unum is seen. if ( p.unum_ != Unum_Unknown ) { M_unum = p.unum_; M_unum_count = 0; if ( ! p.goalie_ ) { // when unum is seen, goalie info is also seen M_goalie = false; } } if ( p.goalie_ ) { M_goalie = true; } const Vector2D last_seen_move = p.pos_ - M_seen_pos; const int last_seen_pos_count = M_seen_pos_count; if ( p.hasVel() ) { M_vel = p.vel_; M_vel_count = 0; M_seen_vel = p.vel_; M_seen_vel_count = 0; #ifdef DEBUG_PRINT dlog.addText( Logger::WORLD, __FILE__" (updateBySee) unum=%d. pos=(%.2f, %.2f) vel=(%.2f, %.2f)", p.unum_, M_pos.x, M_pos.y, M_vel.x, M_vel.y ); #endif } else if ( 0 < M_pos_count && M_pos_count <= 2 && p.rpos_.r() < 40.0 ) { const double speed_max = ( M_player_type ? M_player_type->playerSpeedMax() : ServerParam::i().defaultPlayerSpeedMax() ); const double decay = ( M_player_type ? M_player_type->playerDecay() : ServerParam::i().defaultPlayerDecay() ); M_vel = last_seen_move / static_cast< double >( last_seen_pos_count ); double tmp = M_vel.r(); if ( tmp > speed_max ) { M_vel *= speed_max / tmp; } M_vel *= decay; M_vel_count = last_seen_pos_count; M_seen_vel = M_vel; M_seen_vel_count = 0; #ifdef DEBUG_PRINT dlog.addText( Logger::WORLD, __FILE__" (updateBySee) unum=%d. update vel by pos diff." "prev_pos=(%.2f, %.2f) old_pos=(%.2f, %.2f) -> vel=(%.3f, %.3f)", p.unum_, M_pos.x, M_pos.y, p.pos_.x, p.pos_.y, M_vel.x, M_vel.y ); #endif } else { M_vel.assign( 0.0, 0.0 ); M_vel_count = 1000; } M_pos = p.pos_; M_rpos = p.rpos_; M_seen_pos = p.pos_; M_pos_count = 0; M_rpos_count = 0; M_seen_pos_count = 0; if ( p.hasAngle() ) { M_body = p.body_; M_face = p.face_; M_body_count = M_face_count = 0; } else if ( last_seen_pos_count <= 2 && last_seen_move.r2() > std::pow( 0.2, 2 ) ) // Magic Number { M_body = last_seen_move.th(); M_body_count = std::max( 0, last_seen_pos_count - 1 ); M_face = 0.0; M_face_count = 1000; } else if ( velValid() && vel().r2() > std::pow( 0.2, 2 ) ) // Magic Number { M_body = vel().th(); M_body_count = velCount(); M_face = 0.0; M_face_count = 1000; } if ( p.isPointing() && M_pointto_count >= ServerParam::i().pointToBan() ) { M_pointto_angle = p.arm_; M_pointto_count = 0; } M_kicked = p.kicked(); if ( p.isTackling() ) { if ( M_tackle_count > ServerParam::i().tackleCycles() ) // no tackling recently { M_tackle_count = 0; } } else { M_tackle_count = 1000; } }
/*! */ void ConvexHull::computeDirectMethod() { clearResults(); const size_t point_size = M_input_points.size(); if ( point_size < 3 ) { return; } for ( size_t i = 0; i < point_size - 1; ++i ) { const Vector2D & p = M_input_points[i]; for ( size_t j = i + 1; j < point_size; ++j ) { const Vector2D & q = M_input_points[j]; const Vector2D rel = q - p; bool valid = true; double last_value = 0.0; for ( size_t k = 0; k < point_size; ++k ) { if ( k == i || k == j ) continue; const Vector2D & r = M_input_points[k]; double outer_prod = rel.outerProduct( r - p ); if ( std::fabs( outer_prod ) < 1.0e-6 ) { // point is on the line if ( ( r - p ).r2() < rel.r2() ) { // point is on the segment valid = false; break; } } if ( ( outer_prod > 0.0 && last_value < 0.0 ) || ( outer_prod < 0.0 && last_value > 0.0 ) ) { // point exists in the opposite side valid = false; break; } last_value = outer_prod; } if ( valid ) { M_vertices.push_back( p ); M_vertices.push_back( q ); if ( last_value < 0.0 ) { M_edges.push_back( Segment2D( p, q ) ); } else { M_edges.push_back( Segment2D( q, p ) ); } } } } // sort vertices by counter clockwise order if ( ! M_vertices.empty() ) { std::sort( M_vertices.begin() + 1, M_vertices.end(), AngleSortPredicate( M_vertices.front() ) ); M_vertices.erase( std::unique( M_vertices.begin(), M_vertices.end(), Vector2D::Equal() ), M_vertices.end() ); } }