コード例 #1
0
/*!

*/
void
PlayerControlPainter::draw( QPainter & painter )
{
    const Options & opt = Options::instance();

    if ( ! opt.showKickAccelArea() )
    {
        return;
    }

    int number = opt.selectedNumber();
    if ( number == 0 )
    {
        return;
    }

    MonitorViewConstPtr view = M_main_data.getCurrentViewData();

    if ( ! view )
    {
        return;
    }

    const Ball & ball = view->ball();

    if ( ! ball.hasDelta() )
    {
        return;
    }

    const rcsc::ServerParam & SP = rcsc::ServerParam::i();
    const DrawConfig & dconf = DrawConfig::instance();

    const Player & player = view->players()[ ( number > 0
                                               ? number - 1
                                               : -number - 1 + 11 ) ];
    const rcsc::PlayerType & ptype = M_main_data.viewHolder().playerType( player.type() );

    rcsc::Vector2D ppos( player.x(), player.y() );
    rcsc::Vector2D bpos( ball.x(), ball.y() );
    rcsc::Vector2D player_to_ball = bpos - ppos;
    player_to_ball.rotate( - player.body() );

    rcsc::Vector2D bnext( bpos.x + ball.deltaX(),
                          bpos.y + ball.deltaY() );
    double ball_dist = player_to_ball.r();

    if ( ball_dist < ptype.kickableArea() )
    {
        double max_kick_accel
            = SP.maxPower()
            //* SP.kickPowerRate()
            * ptype.kickPowerRate()
            * ( 1.0 - 0.25 * player_to_ball.th().abs() / 180.0
                - 0.25
                * ( ball_dist - ptype.playerSize() - SP.ballSize() )
                / ptype.kickableMargin() );

        if ( max_kick_accel > SP.ballAccelMax() )
        {
            max_kick_accel = SP.ballAccelMax();
        }

        QPointF bpos_screen( opt.screenXF( bpos.x ),
                             opt.screenYF( bpos.y ) );
        QPointF bnext_screen( opt.screenXF( bnext.x ),
                              opt.screenYF( bnext.y ) );
        double max_speed_screen = opt.scaleF( SP.ballSpeedMax() );
        double max_kick_accel_screen = opt.scaleF( max_kick_accel );

        painter.setPen( dconf.kickAccelPen() );
        painter.setBrush( dconf.transparentBrush() );

        // draw no noise next ball move only by inertia
        painter.drawLine( QLineF( bpos_screen, bnext_screen ) );

        rcsc::Circle2D max_speed_circle( bpos, SP.ballSpeedMax() );
        rcsc::Circle2D max_accel_circle( bnext, max_kick_accel );
        rcsc::Vector2D intersection_1, intersection_2;

        if ( max_speed_circle.intersection( max_accel_circle,
                                            &intersection_1,
                                            &intersection_2 ) != 2 )

        {
            // no intersection points

            // just draw a next ball reachable area by max accel
            painter.drawEllipse( QRectF( bnext_screen.x() - max_kick_accel_screen,
                                         bnext_screen.y() - max_kick_accel_screen,
                                         max_kick_accel_screen * 2,
                                         max_kick_accel_screen * 2 ) );
        }
        else
        {
            // exists 2 intersection points

            rcsc::AngleDeg bpos_to_intersection_1 = ( intersection_1 - bpos ).th();
            rcsc::AngleDeg bpos_to_intersection_2 = ( intersection_2 - bpos ).th();

            rcsc::AngleDeg bpos_to_bnext_angle = ( bnext - bpos ).th();

            rcsc::AngleDeg * bpos_start_angle = 0;
            double bpos_angle_span = 0.0;
            if ( bpos_to_intersection_1.isLeftOf( bpos_to_bnext_angle ) )
            {
                bpos_start_angle = &bpos_to_intersection_1;
                bpos_angle_span = ( bpos_to_intersection_2 - bpos_to_intersection_1 ).degree();
                if ( bpos_angle_span < 0.0 )
                {
                    bpos_angle_span += 360.0;
                }
                bpos_angle_span *= -1.0;
            }
            else
            {
                bpos_start_angle = &bpos_to_intersection_2;
                bpos_angle_span = ( bpos_to_intersection_1 - bpos_to_intersection_2 ).degree();
                if ( bpos_angle_span < 0.0 )
                {
                    bpos_angle_span += 360.0;
                }
                bpos_angle_span *= -1.0;
            }

            if ( opt.reverseSide() )
            {
                *bpos_start_angle += 180.0;
            }

            int bpos_start_angle_int
                = static_cast< int >( rint( - bpos_start_angle->degree() * 16 ) );
            int bpos_angle_span_int
                = static_cast< int >( rint( bpos_angle_span * 16 ) );
            painter.drawArc( QRectF( bpos_screen.x() - max_speed_screen,
                                     bpos_screen.y() - max_speed_screen,
                                     max_speed_screen * 2,
                                     max_speed_screen * 2 ),
                             bpos_start_angle_int,
                             bpos_angle_span_int  );

            rcsc::AngleDeg bnext_to_intersection_1 = ( intersection_1 - bnext ).th();
            rcsc::AngleDeg bnext_to_intersection_2 = ( intersection_2 - bnext ).th();

            rcsc::AngleDeg bnext_to_bpos_angle = bpos_to_bnext_angle + 180.0;

            rcsc::AngleDeg * bnext_start_angle = 0;
            double bnext_angle_span = 0.0;
            if ( bnext_to_intersection_1.isLeftOf( bnext_to_bpos_angle ) )
            {
                bnext_start_angle = &bnext_to_intersection_1;
                bnext_angle_span = ( bnext_to_intersection_2 - bnext_to_intersection_1 ).degree();
                if ( bnext_angle_span < 0.0 )
                {
                    bnext_angle_span += 360.0;
                }
                bnext_angle_span *= -1.0;
            }
            else
            {
                bnext_start_angle = &bnext_to_intersection_2;
                bnext_angle_span = ( bnext_to_intersection_1 - bnext_to_intersection_2 ).degree();
                if ( bnext_angle_span < 0.0 )
                {
                    bnext_angle_span += 360.0;
                }
                bnext_angle_span *= -1.0;
            }

            if ( opt.reverseSide() )
            {
                *bnext_start_angle += 180.0;
            }

            int bnext_start_angle_int
                = static_cast< int >( rint( - bnext_start_angle->degree() * 16 ) );
            int bnext_angle_span_int
                = static_cast< int >( rint( bnext_angle_span * 16 ) );
            painter.drawArc( QRectF( bnext_screen.x() - max_kick_accel_screen,
                                     bnext_screen.y() - max_kick_accel_screen,
                                     max_kick_accel_screen * 2,
                                     max_kick_accel_screen * 2 ),
                             bnext_start_angle_int,
                             bnext_angle_span_int );
        }

        // draw kick info text
        painter.setFont( dconf.playerFont() );
        painter.setPen( dconf.kickAccelPen() );

        //snprintf( buf, 32, "MaxAccel=%.3f", max_kick_accel );
        painter.drawText( QPointF( bnext_screen.x() + 10,
                                   bnext_screen.y() + painter.fontMetrics().ascent() ),
                          QString( "MaxAccel=%1" ).arg( max_kick_accel, 0, 'g', 4 ) );
    }
}
コード例 #2
0
/*!

 */
void
PlayerPainter::drawKickAccelArea( QPainter & painter,
                                  const PlayerPainter::Param & param ) const
{
    //
    // draw kick accel area
    //

    if ( ! param.ball_.hasVelocity() )
    {
        return;
    }

    const Options & opt = Options::instance();
    const rcss::rcg::ServerParamT & SP = M_main_data.serverParam();

    Vector2D ppos( param.player_.x_,
                   param.player_.y_ );
    Vector2D bpos( param.ball_.x_,
                   param.ball_.y_ );

    Vector2D player_to_ball = bpos - ppos;
    player_to_ball.rotate( - param.player_.body_ );

    double ball_dist = player_to_ball.r();

    if ( ball_dist > ( param.player_type_.player_size_
                       + param.player_type_.kickable_margin_
                       + SP.ball_size_ ) )
    {
        return;
    }

    double max_kick_accel
        = SP.max_power_
        //* SP.kick_power_rate_
        * param.player_type_.kick_power_rate_
        * ( 1.0 - 0.25 * player_to_ball.th().abs() / 180.0
            - 0.25
            * ( ball_dist - param.player_type_.player_size_ - SP.ball_size_ )
            / param.player_type_.kickable_margin_ );

    if ( max_kick_accel > SP.ball_accel_max_ )
    {
        max_kick_accel = SP.ball_accel_max_;
    }

    Vector2D bnext( bpos.x + param.ball_.vx_,
                    bpos.y + param.ball_.vy_ );

    QPoint bpos_screen( opt.screenX( bpos.x ),
                        opt.screenY( bpos.y ) );
    QPoint bnext_screen( opt.screenX( bnext.x ),
                         opt.screenY( bnext.y ) );
    int max_speed_screen = opt.scale( SP.ball_speed_max_ );
    int max_kick_accel_screen = opt.scale( max_kick_accel );

    painter.setPen( M_kick_accel_pen );
    painter.setBrush( Qt::NoBrush );

    // draw no noise ball move line
    painter.drawLine( bpos_screen, bnext_screen );

    Circle2D max_speed_circle( bpos, SP.ball_speed_max_ );
    Circle2D max_accel_circle( bnext, max_kick_accel );
    Vector2D intersection_1, intersection_2;

    if ( max_speed_circle.intersection( max_accel_circle,
                                        &intersection_1,
                                        &intersection_2 ) != 2 )
    {
        // no intersection points

        // just draw a next ball reachable area by max accel
        painter.drawEllipse( bnext_screen.x() - max_kick_accel_screen,
                             bnext_screen.y() - max_kick_accel_screen,
                             max_kick_accel_screen * 2,
                             max_kick_accel_screen * 2 );
    }
    else
    {
        // exists 2 intersection points

        AngleDeg bpos_to_intersection_1 = ( intersection_1 - bpos ).th();
        AngleDeg bpos_to_intersection_2 = ( intersection_2 - bpos ).th();

        AngleDeg bpos_to_bnext_angle = ( bnext - bpos ).th();

        AngleDeg * bpos_start_angle = 0;
        double bpos_angle_span = 0.0;
        if ( bpos_to_intersection_1.isLeftOf( bpos_to_bnext_angle ) )
        {
            bpos_start_angle = &bpos_to_intersection_1;
            bpos_angle_span = ( bpos_to_intersection_2 - bpos_to_intersection_1 ).degree();
            if ( bpos_angle_span < 0.0 )
            {
                bpos_angle_span += 360.0;
            }
            bpos_angle_span *= -1.0;
        }
        else
        {
            bpos_start_angle = &bpos_to_intersection_2;
            bpos_angle_span = ( bpos_to_intersection_1 - bpos_to_intersection_2 ).degree();
            if ( bpos_angle_span < 0.0 )
            {
                bpos_angle_span += 360.0;
            }
            bpos_angle_span *= -1.0;
        }

        int bpos_start_angle_int
            = static_cast< int >( rint( - bpos_start_angle->degree() * 16 ) );
        int bpos_angle_span_int
            = static_cast< int >( rint( bpos_angle_span * 16 ) );
        painter.drawArc( bpos_screen.x() - max_speed_screen,
                         bpos_screen.y() - max_speed_screen,
                         max_speed_screen * 2,
                         max_speed_screen * 2,
                         bpos_start_angle_int,
                         bpos_angle_span_int  );

        AngleDeg bnext_to_intersection_1 = ( intersection_1 - bnext ).th();
        AngleDeg bnext_to_intersection_2 = ( intersection_2 - bnext ).th();

        AngleDeg bnext_to_bpos_angle = bpos_to_bnext_angle + 180.0;

        AngleDeg * bnext_start_angle = 0;
        double bnext_angle_span = 0.0;
        if ( bnext_to_intersection_1.isLeftOf( bnext_to_bpos_angle ) )
        {
            bnext_start_angle = &bnext_to_intersection_1;
            bnext_angle_span = ( bnext_to_intersection_2 - bnext_to_intersection_1 ).degree();
            if ( bnext_angle_span < 0.0 )
            {
                bnext_angle_span += 360.0;
            }
            bnext_angle_span *= -1.0;
        }
        else
        {
            bnext_start_angle = &bnext_to_intersection_2;
            bnext_angle_span = ( bnext_to_intersection_1 - bnext_to_intersection_2 ).degree();
            if ( bnext_angle_span < 0.0 )
            {
                bnext_angle_span += 360.0;
            }
            bnext_angle_span *= -1.0;
        }

        int bnext_start_angle_int
            = static_cast< int >( rint( - bnext_start_angle->degree() * 16 ) );
        int bnext_angle_span_int
            = static_cast< int >( rint( bnext_angle_span * 16 ) );
        painter.drawArc( bnext_screen.x() - max_kick_accel_screen,
                         bnext_screen.y() - max_kick_accel_screen,
                         max_kick_accel_screen * 2,
                         max_kick_accel_screen * 2,
                         bnext_start_angle_int,
                         bnext_angle_span_int );
    }

    // draw kick info text
    painter.setFont( M_player_font );
    painter.setPen( M_kick_accel_pen );

    char buf[32];
    snprintf( buf, 32, "MaxAccel=%.3f", max_kick_accel );
    painter.drawText( bnext_screen.x() + 10,
                      bnext_screen.y() + painter.fontMetrics().ascent(),
                      QString::fromAscii( buf ) );
}