0

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)

Gykonik
  • 638
  • 1
  • 7
  • 24
  • from http://glm.g-truc.net/0.9.5/updates.html `Finally, here is a list of all the functions that could use degrees in GLM 0.9.5.4 that requires radians in GLM 0.9.6: rotate (matrices and quaternions), [etc.]` –  Feb 24 '16 at 15:26
  • 1
    the _randRotate(randomEngine))_ part returns a degrees and glm::rotate needs a radian. Thats the solution! Thank you! :) – Gykonik Feb 24 '16 at 15:35

1 Answers1

1

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

Xirema
  • 19,889
  • 4
  • 32
  • 68
  • I looked it up, GLM does use Degrees to calculate rotation – Gykonik Feb 24 '16 at 15:19
  • @Gykonik AFAIR, http://stackoverflow.com/questions/23945139/glm-function-taking-degrees-as-a-parameter-is-deprecated-when-using-radians - GLM can actually use both. Did you check with the value converted passed as angle converted degree-to-radians manually? –  Feb 24 '16 at 15:21
  • Oh, you're right. But it must be degrees, right? How can I do this? I read, that you can use `glm::degrees() //from radians to degrees. ` to convert radians to degrees. Where I should pass it in in the line `glm::rotate(direction, randRotate(randomEngine))`? – Gykonik Feb 24 '16 at 15:31
  • @Gykonik I've just added an edit. As for how to convert, you can either do it manually (`radians = degrees * PI / 180` & `degrees = radians / PI * 180`) or use the built-in functions provided by GLM. – Xirema Feb 24 '16 at 15:34
  • Ok, I solved it by my self. I don't know why and I also don't know, why noone else had this problem before but randRotate(XYZ) returns degrees and glm::rotate needs radians... So I converted it and now it works proper! Thank you for your help! :) – Gykonik Feb 24 '16 at 15:34