Reputation: 195
I searched around and it turns out the answer to this is surprising hard to find. Theres algorithm out there that can generate a random orientation in quaternion form but they involve sqrt and trig functions. I dont really need a uniformly distributed orientation. I just need to generate (many) quaternions such that their randomness in orientation is "good enough." I cant specify what is "good enough" except that I need to be able to do the generation quickly.
Upvotes: 9
Views: 11890
Reputation: 1
There is a matlab function randrot() to generate Uniformly distributed random rotations
https://uk.mathworks.com/help/nav/ref/randrot.html
The reference is "Shoemake, K. 'Uniform Random Rotations.' Graphics Gems III (K. David, ed.). New York: Academic Press, 1992."
On page 129, random quaternion can be generated from the Subgroup Algorithm
Upvotes: 0
Reputation: 1918
Simplest way to generate it, just generate 4 random (normal dist) float and normalize it if required. If you want to produce rotation matrices later , than normalization can be skipped and convertion procedure should note nonunit quaternions.
Upvotes: 0
Reputation: 2601
Quoted from http://planning.cs.uiuc.edu/node198.html:
Choose three points u, v, w ∈ [0,1] uniformly at random. A uniform, random quaternion is given by the simple expression:
h = ( sqrt(1-u) sin(2πv), sqrt(1-u) cos(2πv), sqrt(u) sin(2πw), sqrt(u) cos(2πw))
Upvotes: 16
Reputation: 6317
From Choosing a Point from the Surface of a Sphere by George Marsaglia:
This will generate a uniform random rotation because 4D spheres, unit quaternions and 3D rotations have equivalent measures.
The algorithm uses one square root, one division, and 16/π ≈ 5.09 random numbers on average. C++ code:
Quaternion random_quaternion() {
double x,y,z, u,v,w, s;
do { x = random(-1,1); y = random(-1,1); z = x*x + y*y; } while (z > 1);
do { u = random(-1,1); v = random(-1,1); w = u*u + v*v; } while (w > 1);
s = sqrt((1-z) / w);
return Quaternion(x, y, s*u, s*v);
}
Upvotes: 7