Problem With 2D Acceleration

Started by
4 comments, last by DishSoap 11 years ago

I am using Euler integration to update my position, velocity, and acceleration on a 2D plane. I move characters on screen by a point and click mechanic. I compute the vector the character travels along by taking the destinationVec - positionVec, normalize the resultant vector then mutiply that by some scalar that represents a characters acceleration value. The result is strange, on further distances traveled the character will completely miss the target and start circling around the point I clicked. When I remove the scalar multiplication it works fine with just the normalized vector. I must be rusty on my math or something? So I will post the code:


void navigateToDestination(CollidableObject &character)
{
    sf::Vector2f destinationPx = character.getDestination();
    sf::Vector2f positionPx = character.getPosition();
    sf::Vector2f acceleration = character.getAcceleration();
    sf::Vector2f direction = destinationPx - positionPx;
    vecMath::normalize(direction);
    
    ....

    if(character.getIsMoving())
    {
        acceleration.x = direction.x * character.getAccelerationValue(); <- Which is some float, 10.0f, in this instance
        acceleration.y = direction.y * character.getAccelerationValue(); <- When this acceleration value is removed the path works
    }

    ....

    character.setAcceleration(acceleration);
}

..... Later called function

void updatePosition(double dt) 
{
    setCollisionRect();
    m_position += sf::Vector2f(m_velocity.x * dt, m_velocity.y * dt);
    m_velocity += sf::Vector2f(m_acceleration.x * dt, m_acceleration.y * dt);
    updateCharacter(); // Just limits the acceleration/velocity based on character specific limits
}
 

I've limited the code to what I think might be the problem so I realize you may need to see more to catch something. Please feel free to ask me to post more. Thanks a lot!

Best,

DishSoap

Advertisement

If I think about this conceptually, what I see is the character's velocity continually getting larger and larger the further he travels. Thus, as he approaches the destination, there is a good chance he will "over-shoot" the destination since his velocity may be so large he skips over it during one frame.

A solution would be to check if, during the next update, the character's location difference changes signs (ie, from + to -, or - to +) relative to the destination for a particular axis. Then, the amount moved (ie, velocity) should be lowered to be the distance from the character to the destination. Then you would not over-shoot the destination.

Now, I don't know what you do in UpdateCharacter that you causes the character to either Stop, or be re-route (which would cause the circling), but I assume you could do it there.

Good luck!

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

You can try de-accelerating as you aapproach near the destination. That will make the steps small enough that it won't go right through the destination. (just a theory, haven't tested)

It's like a dropping a ball from rest. At first it has low speed, then reaches max speed right before and right after touching the ground. Then when it goes back up, the speed decreases.

The problem is not the object going through his destination. He vears off either right or left right before arriving at his destination. I have tested the, going through destination, possibility by maxing his velocity and moving him to a nearby point. When clicking close to the character he appropriately arrives, and stops, at his point. It is when he has a fair distance to travel that he vears off before hitting his destination and enters an elliptical or circular path as he tries to correct his acceleration to arrive at the point.

The updateCharacter() method simply sets limits to his acceleration/velocity based on the specific unit. So the velocity and acceleration does not infinitely grow.

I would add an image to show you but I can't figure out how to add images on this website. laugh.png

m_position += sf::Vector2f(m_velocity.x * dt, m_velocity.y * dt);
m_velocity += sf::Vector2f(m_acceleration.x * dt, m_acceleration.y * dt);

That's explicit euler's method, which is well known to be unstable and diverge. Try semi-implicit euler's instead (integrate velocity first) :

m_velocity += sf::Vector2f(m_acceleration.x * dt, m_acceleration.y * dt);

m_position += sf::Vector2f(m_velocity.x * dt, m_velocity.y * dt);

Ah, awesome, that fixed it. Thanks a lot!

This topic is closed to new replies.

Advertisement