Finetuning movement based on gradual rotation towards a target

Posted by A.B. on Game Development See other posts from Game Development or by A.B.
Published on 2013-06-29T15:23:16Z Indexed on 2013/06/29 16:30 UTC
Read the original article Hit count: 564

Filed under:
|
|

I have an object which moves towards a target destination by gradually adjusting its facing while moving forwards. If the target destination is in a "blind spot", then the object is incapable of reaching it.

This problem is ilustrated in the picture below. When the arrow is ordered to move to point A, it will only end up circling around it (following the red circle) because it is not able to adjust its rotation quickly enough.

enter image description here

I'm interested in a solution where the movement speed is multiplied by a number from 0.1 to 1 in proportion to necessity. The problem is, how do I calculate whether it is necessary in the first place? How do I calculate an appropriate multiplier that is neither too small nor too large?

    void moveToPoint(sf::Vector2f destination) {
        if (destination == position) return;

        auto movement_distance = distanceBetweenPoints(position, destination);
        desired_rotation = angleBetweenPoints(position, destination);

        /// Check whether rotation should be adjusted
        if (rotation != desired_rotation) {
            /// Check whether the object can achieve the desired rotation within the next adjustment of its rotation
            if (Radian::isWithinDistance(rotation, desired_rotation, rotation_speed)) {
                rotation = desired_rotation;
            } else {
                /// Determine whether to increment or decrement rotation in order to achieve desired rotation
                if (Radian::convert(desired_rotation - rotation) > 0) {
                    /// Increment rotation
                    rotation += rotation_speed;
                } else {
                    /// Decrement rotation
                    rotation -= rotation_speed;
                }
            }
        }

        if (movement_distance < movement_speed) {
            position = destination;
        } else {
            position.x = position.x + movement_speed*cos(rotation);
            position.y = position.y + movement_speed*sin(rotation);
        }
        updateGraphics();
    }

© Game Development or respective owner

Related posts about c++

Related posts about movement