Archive for Scripting
sphRand and even random distributions on a sphere
Posted by: | CommentsWhile taking an excellent math course over at fxPhd someone asked about the math behind Maya’s sphRand command, and it kicked off a back and forth exploration into the difficulties behind getting an even distribution of random points on a sphere. This is useful for any number of applications where random vectors are needed.
[Note: This topic has been covered (better) elsewhere on the web, but I thought it was interesting enough to preserve for myself on this blog. -am]
So how do you generate a random vector in 3D space? The natural inclination is to generate each point based on a simple random azimuth and elevation. But because the circumference of latitudes decreases from the equator towards the poles, the result is an uneven distribution. Generate a few vectors and things will seem fine. But if you generate a large set of thousands of points, you get this:
But we need an even distribution. How about this: generate random values between -1 and 1 for each X, Y and Z. Then normalize those vectors, and again you have a collection of random points on a sphere. But the distribution still isn’t even… you are basically projecting the points of a cubic volume onto the sphere surface:
You can solve this problem by culling points outside the radius of the sphere (magnitude >1) as they are being generated, and the result is an even distribution on a sphere. This is known as the rejection method, and it works, but it’s inefficient. You are computing a lot of rejected points. Additionally, as a practical matter “N iterations” yields some number less than “N” vectors, making it difficult to specify the total number of vectors to be created by such a function.
Enter the trigonometric method (something of a misnomer seeing as how the method involves the integral of the surface of revolution.)
θ = υ(-1,1)
And Φ = υ(0,2π)
Where υ(a,b) is equal to a uniform random scalar.
So, go from Polar to Cartesian coordinates, and you get:
x = cos(θ) cos(Φ)
y = sin(Φ)
z = cos(θ) sin(Φ)
Digression: if you want to get down to the heart of things, getting a random scalar value, or more specifically a repeatable pseudo-random value based on a specified seed, is it’s own challenge. Here’s a snippet of GLSL code, a function written by Stephen Gustavson which generates a “random” scalar value from a scalar seed input… (cos and mod should be familiar…the “fract” function returns the fractional (decimal) portion of it’s input.)
float randomizer(const float x)
{
float z = mod(x, 5612.0);
z = mod(z, 3.1415927 * 2.0);
return(fract(cos(z) * 56812.5453));
}
threesixty3D
Posted by: | CommentsXSI users may want to check this out, the site has some tools and plugins for XSI, including a free set of ICE compounds, a metaball (pay) plugin, and some very nice scripts.
The $100 euro metaball .addon is pretty nice, many of us have encountered it’s ancestor as the popular free metaball tool which has been around for a while now. Now a grown up product for sale, this plugin adds ICE compatibility as well as the added/cleaner functionality of allowing metaball models to be constructed by hand, through “metapaint” etc. The tool includes not only spherical implicit metaball primitives but cylinders and cubic meta-surfaces, which is a welcome addition. The generated meshes are reasonably clean and can be set to use several models of meshing.
There’s a fair amount in here for the money, feature wise. Usage is pretty straightforward, and the mesh generation is fast. Since ICE users are wanting any mesh generation tools they can get their hands on it’s worth taking a look at the free demo, and my first take is that this tool makes a nice compliment to Eric Mootz’s emPolygonizer. It’s definitely a lot of fun to play with!





