Search code examples
c++vectorrotationglm-math

Rotating 2D vector using glm::rotate


I want to assign a random angle to each projectile based on a spread value. I thought of using glm::rotate for this purpose, but the issue is that the bullets spread in every direction instead of within the specified range.

void Gun::fire(const glm::vec2& direction, const glm::vec2& position, std::vector<Bullet>& bullets) {
    static std::mt19937 randomEngine(time(nullptr));
    // For offsetting the accuracy
    std::uniform_real_distribution<float> randRotate(-_spread, _spread);

    for (int i = 0; i < _bulletsPerShot; i++) {
        // Add a new bullet
        bullets.emplace_back(position, 
                             glm::rotate(direction, randRotate(randomEngine)),
                             _bulletDamage, 
                             _bulletSpeed);
    }   
}

I have included the necessary headers for the vector and glm/gtx/rotate_vector.hpp. Can someone help me understand why the bullets spread in unintended directions and how I can fix it?

Edit: Solution

randRotate(XYZ) returns degrees and glm::rotate needs radians. So we need to convert it using rad = deg * PI / 180 So the proper code would be:

glm::rotate(direction, (randRotate(randomEngine)) * M_PI / 180)

(don't forget t#include <math.h> if you want to use M_PI)


Solution

  • I don't recall if GLM uses Radians or Degrees for calculating rotation, but 2 Radians is nearly a third of a full circle, which means that bullets will vary in direction by as much as 2 thirds of a whole circle. You may wish to test with smaller numbers, or else verify that GLM does indeed use Degrees to calculate rotation.

    EDIT: In the most recent version of GLM, I looked through the source code. There's a commented out version of Rotate that explicitly converts Degrees to Radians, but the accessible source code has no such explicit conversion. So I'm left to presume that it is expecting Radians, not Degrees, as your inputs for Rotation.

    GLM Source Code