Random point on elipsoid (uniform distribution)

Since VFX graph don’t support random position on ellipsoid (surface shell) has anybody got any resources/source on this topic ?

Get sphere position and scale according to the ellipsoid?

It’s not going to be uniform distribution when I do that.

Why not? If you’re using floats, the granularity is microscopic, and won’t be meaningfully changed by stretching it a bit.

It will be, density of distribution will decrease along the stretch axis of ellipsoid.


Basically, if you take a sphere, and stretch it along Z axis, then in a stretched sphere, you’lll have same number of points per unit along X and Y axes, but you’ll have less points per unit along Z.

Also, traditionally ellipsoid is not defined as a stretched sphere.

‘Meaningfully’ means whether or not it matters. Obviously there will be a difference in the number of increments, but there are a lot of decimal points in a float.

Fair enough if an ellipsoid is not a stretched sphere. But we’re game devs, not rocket scientists. Stretching things and hoping no one notices is what we do.

Edit: The google search for ellipsoid says “An ellipsoid is a surface that may be obtained from a sphere by deforming it by means of directional scalings”.

1 Like

I’m not interested in stretching spheres.
There is a way to obtain random uniform points on ellipsoid.
I saw examples but not equations.

Equations. At some point when you start insisting on uncommon fidelity you’re just gonna have to do it yourself.

… have you already tried searching? Because I found this on the first hit:
https://math.stackexchange.com/questions/973101/how-to-generate-points-uniformly-distributed-on-the-surface-of-an-ellipsoid

Yes but I have hoped for something more of a copy paste :wink:

That’s kinda lazy, isn’t it?

I believe you can start with representing point positions as a parametric voxel strip, and then going somewhere from there. For example, let’s say you’re working in 2d and want perfectly uniformly distributed to spawn within a triangle.

You start with a 2d body and overlap it with a grid. You get something like this;
6595387--749707--upload_2020-12-7_2-59-21.png
In essence, you get a bunch of points that can be a spawn position. The thing is, the entire set of points can be represented by a 1D linear array of coordinates of all valid grid cells, and selecting a perfectly uniformly distributed point would be a matter of picking one cell from that array. The cells in array are not necessarily unordered, for example, they could be ordered in a way that cells follow one after another as if you were walking grid left to right, top to bottom (start at the left, move to the right one cell at a time, when you reach the end, start at the left one row below).

Now, although this brings memories of Morton codes (https://en.wikipedia.org/wiki/Z-order_curve), trying to build an array of all valid points is not a useful thing, and likely neither is trying to make a “virtual” parametric array that maps a scalar to a cell position.

However, what is possible to do is to try to establish mapping between possibility of a point spawning and its location, so you could, for example, represent a triangle as a square.
6595387--749710--upload_2020-12-7_3-10-29.png
So your function would take an input of x and y coordinates, which would be uniformly distributed within 0…1 range, and compute coordinates within triangle based on that. For example pTrig = lerp(lerp(aTriangle, bTriangle, y), lerp(aTriangle, cTriangle, y), x);
However, before computing coordinates within triangle it would adjust both x and y coordinates in order to accomodate for distribution of points in target body…, so a point with y = 1 would be less likely to occur than a point with y = 0.

Alright, does anyone understand that and is someone willing to transalte this into a human language?

2 Likes

Or here is a better analogy.

Imagine that your target figure is 3d printed with 100% fill. In essence you have a long wire laid out in shape of the figure.
Now, given a single scalar in range of (0… lengthOfWire), you’ll get unique point within the figure. And depending on type of fill, this point can be calculated parametrically based on the scalar.

Now… this will work with pretty much anything, but the issue here is that in this scneario a point has a size which is thickness of a wire, and if you keep decreasing the size, the length of the wire becomes infinity.

Now… let’s instead of that all points within the body can be calculated based on parameters within 0…1 range. Say, you have a function which takes x/y/z within 0…1 range, and it returns a point within the body. (or on its surface, depending on what you’re doing).

However, such points will not be distributed uniformly. Meaning if you take uniformly distributed input, and feed it into function, you’ll have area that is denser in some places compared to other places.

To combat that you add a filter. That takes input uniform coordinates, and adjusts them in such way that while the values still remain in 0…1 range, if the filtered output is fed into “body point” function, the result will be uniform.

In practice that means that if you, say, have a square pyramid, then, for example, x/y will map to points at specific height of pyramid and remain unchanged, but Z will be filtered in such way that values closer to zero (0 → bottom of the pyramid) will be more likely to occur, while values closer to one (1 → tip of the pyramid) will be more likely to occur.

The filter will be related to density of the function that maps coordinates to body position given uniform input.

So, something like that.


I think this one should be more human readable, and starting from here it should be possible to arrive at a uniform point generation.

1 Like

Actually I know how to do it theoretically the problem is time and difficulty of math involved.
The effort just might not be worth it.
This is why I posted the question, random on ellipsoid did not sound like such an uncommon situation that I would have to do it myself.

It is an uncommon situation, because peole prefer to deal with spheres.

1 Like

@koirat , the question is, why does it have to be distributed precisely in your case?
What you try to do exactly?
Are you making some sort of simulation?
If this is just visual effect, why precision does it matter?
Most people won’t care, or won’t be fussy about some minor visual imperfections.
Smoke and mirrors works wonders in most cases.

Mind, I am not against OP question, as is perfectly valid. Just trying understand the problem, OP is dealing with.

I need it to uniformly distribute vfx particles around arbitrary colliders.
I would like to use one vfx for all type of colliders and since there are no conditional blocks in vfx I have to create custom spawning.
The best for it is ellipsoid since it can do perfect spheres can relatively well approximate capsules, boxes or mesh bounding boxes.

Try making a distribution on a Mathf.OnUnitSphere * longestEllipsoidDiameter + aWeeBit and for each point cast the vector back to the center of the ellipsoid and where that vector intersects with the ellipsoid then that is the position of that point. If yer just doing this on a one off and not a Update basis then you could further loop thru and get an average distance by SphereCasting to find neighbors and then jittering those whose distances to neighbors are too close or far from the average. You could then pass that point array to the ParticleSystem

I need it to be inside vfx graph (many particles).
If nobody provide direct analytical method I will be reconsidering implementing it by myself.