Houdini VEX - Random Directed Vectors
This is a great way of getting “random” vectors but you need the vectors to be “clamped” to a certain range of “spread”.
To illustrate this, we’ll use a buncha points on a grid and “shoot” (aka move) them out “randomly” using sample
functions.
1. Sample Direction Uniform
vector2 u = rand(@ptnum);
@P = sample_direction_uniform(u);
Which gets us, well, a buncha points scattered in every direction.
2. Sample Hemisphere
This function takes a center
and a bias
. Think of “center” in sample functions as “direction” – so {0, 1, 0}
is up, {0, -1, 0}
is down – and bias
is simply the “angle of spread”.
vector2 uv = rand(@ptnum);
float bias = @Frame;
@P = sample_hemisphere({0, 0, 0}, bias, uv);
This function by default goes in +x
– as bias
increases, the points converge on the “horizon”.
3. Sample Direction Cone
This is probably the most useful, instead of bias
we just use angle
instead to achieve something similar. This time, we’ll scatter upwards using {0, 1, 0}
as the center.
vector2 uv = rand(@ptnum);
float angle = 90; // the "spread" of the cone
@P = sample_direction_cone({0, 1, 0}, radians(angle), uv);
We could imagine using this to shoot out random particles, so instead of @P
we could assign it to @v
as initial velocity to a DOP – while constraining how far they spread.
But what happens if we want the magnitudes to be the same? Right now, we have some vectors that are ahead of others because it’s a dome-like spread.
We achieve this by only varying v
in the uv
.
vector2 uv = set(1, rand(@ptnum))
@P = sample_direction_cone({1,0,0}, radians(angle), uv);
Now the values are “clamped” along whichever axis the center is on e.g. all the points have the same @P.x
value – since we are scattering in {1, 0, 0}
.
Another way of thinking about this, if we have particles getting shot out in +x
direction, they can only vary/wiggle up-down (y) or left-right (z) but how far they go (x) is always the same across all points.
At radians(90)
the vectors are perpendicular to the projection plane. We can use this to randomly scatter lines that are perfectly flat on the ground but point in different directions:
// Before a Copy to Points SOP
@N = sample_direction_cone({0, 1, 0}, radians(90), set(1, rand(@ptnum)));
4. Sample Hypersphere Uniform
This is a quick way to randomly rotate a bunch of girls around in a Copy to Points e.g. get a random @orient
.
@orient = sample_hypersphere_uniform(rand(@ptnum));