[x,y,z] =
CreateUniformDotsIn3DFrustum(ndots,FOV,aspectr,depthrangen,depthrangef,eyeheight)
Sample dots in frustum uniformly, creating a cloud tightly fitting in the
frustum. When the optional 6th parameter eyeheight is given, dots will be
uniformly sampled on a ground plane at -eyeheight.
z is not sampled from a uniform distribution, but from a parabolic
distribution as the area of cross sections of the frustum is a quadratic
function of the depth plane's depth ( (z*2*tan(FOV/2))^2 * aspectr )
Here, I use Inverse transform sampling to transform a uniform random
variable into the quadratic shape random variable
see Luc Devroye. Non-Uniform Random Variate Generation. New York:
Springer-Verlag, 1986. Chapter 2
(
http://cg.scs.carleton.ca/~luc/chapter_two.pdf)
\documentclass[12pt,a4paper]{minimal}
\usepackage{amsmath} % math
\begin{document}
\textbf{Derivation}:\\
Use pdf related to cross-section surface of frustum:
\(\left(2 z \tan\left(\frac{FOV}{2}\right)\right)^2 aspectr\)\\
\(z_1\) is the distance of the near depth plane\\
\(z_2\) is the distance of the far depth plane\\
\(y\) is a uniform random variable\\
Given: \(F(z_2)=1\) and \(F(z_1)=0\).
\begin{align}
F(z) &= \int\limits^z_{z_1} k z^2 \, \mathrm{d}z\\
F(z) &= \frac{k}{3} \left(z^3 - z_1^3\right)\\
k &= \frac{3}{z_2^3-z_1^3}\\
F(z) &= \frac{z^3-z_1^3}{z_2^3-z_1^3}
\end{align}
Substitute \(y\) for \(F(z)\) and factor out \(z\):
\begin{align}
z^3 &= y\left(z_2^3-z_1^3\right) + z_1^3\\
z &= \sqrt[3]{y\left(z_2^3-z_1^3\right) + z_1^3}
\end{align}\\
For a ground plane, the width of the frustum at depth \(z\) is given by
\(2 z \tan\left(\frac{FOV}{2}\right) aspectr\).\\
By following the same inverse transform sampling steps, we would end up
with
\[ z = \sqrt{y\left(z_2^2-z_1^2\right) + z_1^2} \]
for the linear distribution between \(z_1\) and \(z_2\).
\end{document}
Psychtoolbox/PsychOneliners/CreateUniformDotsIn3DFrustum.m