Velocity vector troubles

This is a discussion on Velocity vector troubles within the Game Programming forums, part of the General Programming Boards category; In my recent asteroids clone I've encountered a lot of problems with the velocity vector of the ship and the ...

  1. #1
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596

    Velocity vector troubles

    In my recent asteroids clone I've encountered a lot of problems with the velocity vector of the ship and the actual rotation angle of the ship.

    What I'm currently doing is when the user presses a rotate key (left or right arrow if it has not been re-assigned) I simply change the Z rotation of the ship without altering the velocity vector. The velocity vector is only altered when the user presses the thrust key (up arrow). This makes for a really cool floating type effect where you can actually be heading in one direction but have your ship pointed in another firing on whatever you need to fire on.

    Big problem: I cannot clamp the velocity vector to reasonable values using this method. In other words it's possible to speed the ship up to some insane rates - to the point of not being able to distinguish what is going on in the game with your ship.

    Code:
    void GetKeys(void)
    {
       Keyboard.Update();
    
       if (Keyboard.KeyDown(AST_LEFT))
       {
          Ship.Rotate(LEFT);
          Ship.ZRotation.x=cos(Ship.GetAngle());
          Ship.ZRotation.y=sin(Ship.GetAngle());
       }
       if (Keyboard.KeyDown(AST_RIGHT))
       {
          Ship.Rotate(RIGHT);
          Ship.ZRotation.x=cos(Ship.GetAngle());
          Ship.ZRotation.y=sin(Ship.GetAngle());
       }
    
       if (Keyboard.KeyDown(AST_THRUST))
      {
         Ship.VelVector+=(Ship.ZRotation);
      }

    Solutions I've tried:

    Keep the velocity vector normalized and multiply the normalized vector by a scalar speed amount.
    Problem: Since the speed value is a scalar, you cannot simply increase it every time the user presses the thrust key. This results in the velocity vector overshooting the actual rotation vector - the ship goes nuts.

    Clamp the velocity vector components to certain ranges
    This works but since you are clamping based on range instead of x/y relation the final velocity vector might not represent the actual rotation vector. For instance clamping x and y to .50 while having a rotation vector of 135 would not work.

    Clamp based on the length of the velocity vector
    This works until you max the length - then there is no way to lessen the length because the thrust key is effectively locked out, thus the length stays constant.


    I'm open to any ideas you might have.

  2. #2
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704
    It seems that the thrust should be a set ammount, say 0.25f.
    normalize the direction vector of the thrust (ie ships pointing direction) and multiply that vector by the 0.25f scaler.
    Then add this new acclereation vector to the current velocity vector of the ship.
    Code:
     If accel vector+velocity vector > max velocity scaler
         velocity vector = normalize( velocity vector + accel vector ) * max velocity 
     else if accel vector + velocity vector <= max velocity scaler
         velocity vector = velocity vector + accel vector
    I'm pretty sure that method should achieve desired results.
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  3. #3
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704
    PS: (4:57am my time) I've uploaded a javascript demonstration, mostly for my own exercise in coding since it's been a while and I need to warm up for next semester but to also show you what I meant.

    try http://www.jeremygiberson.com/javascripts/velocity.html (ie only, my scripts too hard for mozilla ;p)


    edit: standard W,S,A,D controlls the ship.
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  4. #4
    Registered User
    Join Date
    Mar 2003
    Posts
    580
    Pretty much what jeremy said:

    The orientation of the thrust should be some normalized direction. When the user presses 'forward', you apply a force in that direction, that force over the mass of the spacecraft is the acceleration.

    dt is the change in time for the frame. Use this if you want the force to be applied continuously. If this is an 'impulse' force, i.e a force that acts over a very very short (infinitely small) period of time, get rid of the dt and come up with some realistic values for the impulse

    if(FORWARD)
    {
    Vector Force = Spacecraft.ForwardOrientationVector * ForceMagnitude * dt;

    Vector Accel = Force * (1/Spacecraft.Mass);

    Spacecraft.WorldspaceVelocity += Accel;

    }


    that's the basic idea
    See you in 13

  5. #5
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Isn't that what he is already doing?


    Wouldn't this method work?
    Code:
    if |vel| > max 
      vel = max/|vel|  * vel
    Do not lock the thrust key, just keep this check afterwards!
    That way you'll still be able to change the velocity the way you are doing it now.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  6. #6
    Registered User linuxdude's Avatar
    Join Date
    Mar 2003
    Location
    Louisiana
    Posts
    926
    I agree with Sandrax. Use the magnitude of the vector determine if it is greater than max. then if so normalize it to max. What is wrong with that.

  7. #7
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    If you read my post I already tried to clamp based on the magnitude of the vector but it does not work. Problem is that even though the magnitude of the vector might be at some value that is no guarantee that the ship is moving only in that direction. A magnitude implies that regardless of direction we clamp....which is not good because it is possible to clamp the vector even though it does not line up with the z rotation of the ship.

    For instance. Press forward several times to thrust. Press left and right to rotate - stop the rotation near, but not at, the same rotation angle that you thrusted at to start with. Now apply lots of thrust in this direction. The magnitude of the resulting vector will clamp before your ship actually begins to follow the new z rotation of your ship because the first vector was so large. In essence:

    1. Rotate to face right (90 degrees in my setup), thrust several times.
    2. Rotate right 90 degrees to face down. Thrust several times.
    3. If you clamp on magnitude the ship will face straight down (180 in my setup), but the resulting vector will clamp somewhere between 90 and 180 since the magnitude does not care about direction, it only cares about a scalar quantity.

    So this won't work.

    Code:
    ...
    float dist=D3DXVec3Length(&Ship.VelVector);
    if (dist<some_scalar)
    {
       //add thrust
    } else //don't add thrust
    ...
    Also if you notice when the vector does finally clamp...you cannot add any more thrust because there is no way to decrease it's magnitude since the vector summation happens inside of the condition that assumes the length or magnitude is less than some scalar quantity.

    if(FORWARD)
    {
    Vector Force = Spacecraft.ForwardOrientationVector * ForceMagnitude * dt;

    Vector Accel = Force * (1/Spacecraft.Mass);

    Spacecraft.WorldspaceVelocity += Accel;

    }
    This is what I'm doing minus the physics. I'm not using actual physics in the game since it's just an asteroids clone.
    And I don't need a speed_scalar to multiply by since I'm only doing vector summation, thus when the velocity vector lines up with the z rotation of the ship, the ship acceleration along that vector is increased since the velocity vector now is no longer normalized.
    Last edited by VirtualAce; 01-17-2005 at 11:47 PM.

  8. #8
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Quote Originally Posted by Bubba
    For instance. Press forward several times to thrust. Press left and right to rotate - stop the rotation near, but not at, the same rotation angle that you thrusted at to start with. Now apply lots of thrust in this direction. The magnitude of the resulting vector will clamp before your ship actually begins to follow the new z rotation of your ship because the first vector was so large.
    Not using the method I posted. The direction of the velocity will always approach the new direction.

    The ship will hit max speed, true, but the direction of the velocity will still change because you aren't disabling the thrust key when the speed is at the maximum.
    Code:
    float dist=D3DXVec3Length(&Ship.VelVector);
    if (dist<some_scalar)
    {
       //add thrust
    } else //don't add thrust
    There's your problem. The thrust key should always be able to add thrust, then use the simple check I posted to keep the magnitude of the velocity vector below the limit.
    Last edited by Sang-drax; 01-18-2005 at 09:42 AM.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  9. #9
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    Ok I think I'm understanding. In other words clamp the magnitude of the vector, but prior to that go ahead and do the vector summation so that the thrust key works. I'm locking the thrust key out not by literally locking it out, but by clamping the final value.

    Like this:

    Code:
    
    x+=increment;
    if (x>some_scalar)  x=max_value;
    This allows x to still increment yet when it maxes, it is clamped to a max value.

    That makes sense. Not sure why this threw me for a loop. I've been working with so much other math pertaining to 3D as well as scripts, vertex/pixel shaders...my head is spinning.

    Thanks a bunch Sang-drax for clearing this up.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Velocity in rotation using 2D vectors???
    By blackCat in forum Game Programming
    Replies: 1
    Last Post: 04-10-2009, 09:16 AM
  2. Velocity of an object
    By hdragon in forum Game Programming
    Replies: 1
    Last Post: 03-16-2006, 12:35 PM
  3. orientation from velocity
    By ichijoji in forum Game Programming
    Replies: 2
    Last Post: 08-28-2005, 07:22 PM
  4. Reference to making breakout game
    By Raison in forum Game Programming
    Replies: 10
    Last Post: 12-31-2004, 04:18 PM
  5. gravity effecting velocity
    By Josh Kasten in forum Game Programming
    Replies: 4
    Last Post: 02-08-2003, 08:22 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21