Random rotation

I had to put an object in random rotation (for my dice-throwing subproject). It had to be really uniformly random, so the results would be also reasonably random. It turns out that you cannot just rotate object by random angles and hope it will be ok. Here is a bit of code which generates random quaternion with uniform distribution (each orientation has same chance of happening) - given of course, quality of Math.random(), you can replace it with your favorite Marsenne-prime super-hyper-random thing if you wish.



[java]

public static Quaternion randomQuaternion() {

double u1 = Math.random();

double u2 = Math.random();

double u3 = Math.random();





double u1sqrt = Math.sqrt(u1);

double u1m1sqrt = Math.sqrt(1-u1);

double x = u1m1sqrt Math.sin(2Math.PIu2);

double y = u1m1sqrt Math.cos(2Math.PI
u2);

double z = u1sqrt Math.sin(2Math.PIu3);

double w = u1sqrt Math.cos(2Math.PI
u3);



return new Quaternion((float)x,(float)y,(float)w,(float)z);

}

[/java]



It is implementing algorithm described in

Generating a random element of



Maybe we could consider adding it to Quaternion itself ? I would imagine method like .randomLocal(float u1, float u2, float u3), where you can pass your uniformly generated randoms (and possibly shortcut method without parameters, which would use Math.random() for less picky people).



Edit: corrected a mistake sin->cos

Do a new Quaternion with 4 math randoms

then normalize it, after that it represents a rotation.



I’m not completly sure about the distribution, but I think it should be uniform.

I have done a quick test by drawing point sphere representing rotated up vectors. My solution is bit worse (there is a small cluster of higher-density at one place), your one produces very evenly distributed points.



Unfortunately, this is not showing the actual rotation around the axis, just axis itself. Article that I have linked to is scaring me into thinking that rotations are bit more complicated - but to be honest, this is way over top of my head at the moment. I don’t like the clustering around one of the poles with the method I have implemented, but I’m not sure if simply generated quaternion space is evenly distributed after normalization (same way as doing random vector3f [-1,1] and normalizing would produce sphere, but it would be more dense around corners).



Edit:

I have found the link which originally put me to look for more complicated solution

Rotation matrix - Wikipedia


We sometimes need to generate a uniformly distributed random rotation matrix. It seems intuitively clear in two dimensions that this means the rotation angle is uniformly distributed between 0 and 2π. That intuition is correct, but does not carry over to higher dimensions. For example, if we decompose 3×3 rotation matrices in axis-angle form, the angle should not be uniformly distributed; the probability that (the magnitude of) the angle is at most θ should be 1⁄π(θ − sin θ), for 0 ≤ θ ≤ π.

Still, this is about axis-angle not about quaternion...

Well depends the rotations are near to not being imaginable , due to being hypercomplex numbers (3 imginary elements)^^



Just normalize them, they have a method for that, (probably the setRotation did that already, as only normalized quaternions can be projected into a 3d space, else the values just make no sense) and test what happens

It turns out I have made a stupid type above - instead of sin,con,sin,cos I had sin,con,sin,sin. Joys of copy/paste…



Now, when comparing, I can see a small difference other direction - my method is giving really evenly distributed points, while yours is causing some banding around major axis.



Below are the views from inside the sphere of points generated by rotating (1,0,0) vector by generated quaternion.



Simple solution (just 4 randoms directly to quaternion and normalize afterwards)





One from planning book

Hm yeah, seems like mine does cluster a bit around the middle :wink: