user17739521
user17739521

Reputation: 195

How to generate a random quaternion quickly?

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

Answers (4)

Song
Song

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

minorlogic
minorlogic

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

Andrew Hundt
Andrew Hundt

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

Řrřola
Řrřola

Reputation: 6317

From Choosing a Point from the Surface of a Sphere by George Marsaglia:

  1. Generate independent x, y uniformly in (-1..1) until z = x²+y² < 1.
  2. Generate independent u, v uniformly in (-1..1) until w = u²+v² < 1.
  3. Compute s = √((1-z) / w).
  4. Return the quaternion (x, y, su, sv). It's already normalized.

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

Related Questions