Random sampling of points (directions) on a sphere and hemisphere. Useful e.g. for ray-tracers.
Most of the implementation based on "Global Illumination Compendium" IV.B [http://www.cs.kuleuven.ac.be/˜phil/GI/]. See also images there, they help to illustrate the meaning of some functions here.
We use two ways to represent points on hemisphere:
Functions without "XYZ" suffix return vector of 2 floats = two angles, called phi and theta (in this order). Phi (in [0, 2*Pi]) is an angle from some chosen meridian. Theta (in [0, Pi/2] for hemisphere and [0, Pi] for sphere) is an angle from chosen vector pointing outward from the (hemi)sphere. See images in "Global Illumination Compendium", they are probably much easier to understand than this definition.
Functions with "XYZ" suffix return 3D point x, y, z.
(0, 0, 0) is the center of (hemi)sphere,
(0, 0, 1) is the chosen outward vector (i.e. Theta = 0 there),
(1, 0, 0) is the direction where Phi = 0 and Theta = Pi/2,
(0, 1, 0) is the direction where Phi = Pi/2 and Theta = Pi/2.
This is matching conventions in "Global Illumination Compendium", see there (point 21).
Functions with Density <> Const return PdfValue for returned point, i.e. for density p(Theta) it's PfdValue = p(Result[1]). These functions try to calculate PdfValue smartly (often calculating PfdValue and calculating Result uses the same intermediate calculation, so we can save some computation). PdfValue is needed for importance sampling.
Convert from PhiTheta representation of (hemi)sphere direction to XYZ representation.
This is the more advanced version where you can freely specify which vector is the "main outside (hemi)sphere vector", SphereTheta0. Points with Theta = 0 are exactly on SphereTheta0. It is undefined where point like (Phi = 0, Theta = Pi/2) (or any other point with Theta <> 0) will be placed, i.e. it's not defined where's the "chosen meridian" for Phi = 0. However it's defined that this meridian will be determined only by SphereTheta0, and this is usually sufficient (since this makes sure that sampling and then converting to XYZ multiple points with the same SphereTheta0 will preserve sampled density).
Note that the length of SphereTheta0 determines also the sphere radius.