Thread: Calculating a velocity based on two coordinates.

  1. #1
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320

    Calculating a velocity based on two coordinates.

    I am trying to code velocity for a player at some position to move to another position. The velocity will be based off a maximum move speed.

    My thought process is to make a ratio then take that ratio and multiply it by the difference between the two points on the x-axis then take the move speed and multiply it to get the final move speed in the y-axis. Repeat for y-axis. The code I have at the moment will not move me at all and I am unsure why.
    move_speed is 15. In case you all are wondering.

    Code:
    void Player::update()
    {
        if((clock() - Last_Update) > 50)
        {
            float ratio = (abs(grapple_x-x_coord)+abs(grapple_y-y_coord))/(abs(grapple_x-x_coord)*abs(grapple_y-y_coord));
            x_vel = move_speed*ratio*(grapple_x-x_coord);
            y_vel = move_speed*ratio*(grapple_y-y_coord);
            Last_Update = clock();
            x_coord += x_vel;
            y_coord += y_vel;
            if(x_coord < 0)x_coord = 0;
            if(x_coord > 960)x_coord = 960;
            if(y_coord < 0)y_coord = 0;
            if(y_coord > 704)y_coord = 704;
        }
    
    }
    Last edited by ~Kyo~; 02-17-2011 at 01:06 PM.

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Use 2D vectors. They're easier to implement and understand.
    Devoted my life to programming...

  3. #3
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320
    Ahh I forgot to cast the abs() into floats now it is working. Too bad it does have a slight glitch with jumping over a spot that is between two movements, but that doesn't seem as bad.

  4. #4
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320
    The final code... Works like a charm too.

    Code:
    void Player::update()
    {
        if((clock() - Last_Update) > 50)
        {
            Last_Update = clock();
            if(grapple_x != -1 && grapple_y != -1)
            {
    
                if(x_coord != grapple_x)x_vel = move_speed*(double)(grapple_x-x_coord)/((double)abs(grapple_y-y_coord)+(double)abs(grapple_x-x_coord));
                else x_vel = 0;
                if(y_coord != grapple_y)y_vel = move_speed*(double)(grapple_y-y_coord)/((double)abs(grapple_y-y_coord)+(double)abs(grapple_x-x_coord));
                else y_vel = 0;
                x_coord += x_vel;
                y_coord += y_vel;
                if(abs(x_coord-grapple_x) < move_speed+1 && abs(y_coord-grapple_y) < move_speed+1){grapple_x = -1;grapple_y = -1;}//correcting for being close, but not on top of a coordinate keeps player from spasming.
            }
    
            if(x_coord < 0)x_coord = 0;
            if(x_coord > 960)x_coord = 960;
            if(y_coord < 0)y_coord = 0;
            if(y_coord > 704)y_coord = 704;
        }
    
    }
    Last edited by ~Kyo~; 02-17-2011 at 02:24 PM.

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Just FYI, it might simplify things a bit to encapsulate common operations into (preferably generic) functions, eg:

    Code:
    template < typename Type >
    inline void clamp( Type& value, Type const& low, Type const& high ) 
    {
    	if( value < low )
    		value = low;
    	else if( value > high ) 
    		value = high;
    }
    ...then you could rewrite that bit like so:

    Code:
    void Player::update()
    {
        if((clock() - Last_Update) > 50)
        {
            Last_Update = clock();
            if(grapple_x != -1 && grapple_y != -1)
            {
    
                if(x_coord != grapple_x)x_vel = move_speed*(double)(grapple_x-x_coord)/((double)abs(grapple_y-y_coord)+(double)abs(grapple_x-x_coord));
                else x_vel = 0;
                if(y_coord != grapple_y)y_vel = move_speed*(double)(grapple_y-y_coord)/((double)abs(grapple_y-y_coord)+(double)abs(grapple_x-x_coord));
                else y_vel = 0;
                clamp< double >( x_coord += x_vel, 0, 960 );
                clamp< double >( y_coord += y_vel, 0, 704 );
                if(abs(x_coord-grapple_x) < move_speed+1 && abs(x_coord-grapple_y) < move_speed+1){grapple_x = -1;grapple_y = -1;}//correcting for being close, but not on top of a coordinate keeps player from spasming.
            }		
        }
    }
    Just a suggestion.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320
    Yea that does work well ended up changing from double to int for that part though. Only really need the doubles for the abs() calls. First time ever using a template I understand whats going on except with the keyword inline not sure exactly what it is telling the compiler.

    Don't really need the & on the const vars do we? Not changing emm hence const...
    Last edited by ~Kyo~; 02-17-2011 at 06:26 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Grouping Question
    By baikal_m in forum C Programming
    Replies: 7
    Last Post: 10-26-2010, 04:41 PM
  2. Runtime problem
    By SantoshN in forum C Programming
    Replies: 2
    Last Post: 10-12-2010, 02:42 PM
  3. values into array based on coordinates
    By BabyWasabi in forum C++ Programming
    Replies: 1
    Last Post: 12-13-2006, 07:48 PM
  4. Velocity vector troubles
    By VirtualAce in forum Game Programming
    Replies: 8
    Last Post: 01-18-2005, 11:40 AM
  5. Converting from Screen to World Coordinates
    By DavidP in forum Game Programming
    Replies: 9
    Last Post: 05-11-2004, 12:51 PM