Skip to main content
re-word for grammer and brevity, remove implied and subjective language
Source Link

There are multiple algorithm whichalgorithms we can use to generate such point locations and radii. Some of which are iterative, other thatothers are generative but(but expensive), and others that are "approximative""approximative." We don't really care about execution time because the output is readily cached. Perfect packing is not needed as well becauseeither since smaller circles will nearly never be seen. From that, we are going to construct a simple algorithm to generate the spheres locations and radiiusually go unnoticed.

  • Initialize an empty vector and float lists for locations and radii.
  • Define a function that generates a random location, preferably uniform in density.
  • For some arbitrary amountnumber:
  • Generate a random point $p$.
  • Loop over the point and radii lists and compute the smallest signed distance between the point $p$ and the nearest sphere surface point.
  • If the signed distance is positive, that is, (meaning the point is outside all of the existing spheres), append thethat point $p$ and and the radii which(which is defined as any scalar that is smaller that or equal the positive distance.
  • End loop).

The smallest signed distance between the point $p$ and the nearest surface point is equal to the distance between $p$ and the nearest sphere minus its radius. This can be illustarted by looking at this simple diagram:

If the distance is smaller than the radius, then the signed distance will be negative, telling us that the point $p$ is inside of the spheres, and that's why we don't append it. Moreover, the radius of the sphere at point $p$ has to be smaller thatthan the positive distance so as not to intersect the other circle.

The implementation is simple, toTo find the smallest signed distance, we loop over the point and radii lists and reassign an initially infinity float parameter if the current signed distance is smaller than the value of the parameter. This is is the equivalent ofto a KD Tree search except we are subtracting some value defined as the radius. The implementation is as follows:

The rest of the implementation is easy. WeNext, we create a loop that havehas an arbitrary number of iterations controlling the maximum possible amountnumber of spheres, however. However, it does not strictly define the amountnumber of spheres itself  ! The loop has two main parameters,: (1) a vector list that will include the spheres locations and (2) a float list that will contain the radii locations, both. Both inputs are not definedundefined, meaning that they are initially empty lists that we will append to later. In this loop, we generate a random point (Wewe will talk about that algorithm later on), compute the smallest signed distance using the loop we created before and append the sphere location if and only if it is positive. The append condition is implemented as a form of reassign condition for both lists, it. It is important that we inforce copyingcopy the lists at each iteration thus making sure, ensuring the append doesn't overwrite the original list rendering our reassign condition useless. I chose to define the radius as the positive distance bounded by some arbitrary constant called the Max Radius, though any other positive value less than the distance will work. The implementation is as follows:

There are multiple algorithm which we can use to generate such point locations and radii. Some of which are iterative, other that are generative but expensive and others that are "approximative". We don't really care about execution time because the output is readily cached. Perfect packing is not needed as well because smaller circles will nearly never be seen. From that, we are going to construct a simple algorithm to generate the spheres locations and radii.

  • Initialize an empty vector and float lists for locations and radii.
  • Define a function that generates a random location, preferably uniform in density.
  • For some arbitrary amount:
  • Generate a random point $p$.
  • Loop over the point and radii lists and compute the smallest signed distance between the point $p$ and the nearest sphere surface point.
  • If the signed distance is positive, that is, the point is outside all of the existing spheres, append the point $p$ and and the radii which is defined as any scalar that is smaller that or equal the positive distance.
  • End loop.

The smallest signed distance between the point $p$ and the nearest surface point is equal to the distance between $p$ and the nearest sphere minus its radius. This can be illustarted by looking at this simple diagram:

If the distance is smaller than the radius, then the signed distance will be negative, telling us that the point $p$ is inside of the spheres, and that's why we don't append it. Moreover, the radius of the sphere at point $p$ has to be smaller that the positive distance so as not to intersect the other circle.

The implementation is simple, to find the smallest signed distance, we loop over the point and radii lists and reassign an initially infinity float parameter if the current signed distance is smaller than the value of the parameter. This is is the equivalent of a KD Tree search except we are subtracting some value defined as the radius. The implementation is as follows:

The rest of the implementation is easy. We create a loop that have an arbitrary number of iterations controlling the maximum possible amount of spheres, however, it does not strictly define the amount itself  ! The loop has two main parameters, a vector list that will include the spheres locations and a float list that will contain the radii locations, both inputs are not defined, meaning that they are initially empty lists that we will append to later. In this loop, we generate a random point (We will talk about that algorithm later on), compute the smallest signed distance using the loop we created before and append the sphere location if and only if it is positive. The append condition is implemented as a form of reassign condition for both lists, it is important that we inforce copying the lists at each iteration thus making sure the append doesn't overwrite the original list rendering our reassign condition useless. I chose to define the radius as the positive distance bounded by some arbitrary constant called the Max Radius, though any other positive value less than the distance will work. The implementation is as follows:

There are multiple algorithms we can use to generate point locations and radii. Some are iterative, others are generative (but expensive), and others are "approximative." We don't really care about execution time because the output is readily cached. Perfect packing is not needed either since smaller circles will usually go unnoticed.

  • Initialize an empty vector and float lists for locations and radii.
  • Define a function that generates a random location, preferably uniform in density.
  • For some arbitrary number:
  • Generate a random point $p$.
  • Loop over the point and radii lists and compute the smallest signed distance between the point $p$ and the nearest sphere surface point.
  • If the signed distance is positive (meaning the point is outside all of the existing spheres), append that point $p$ and radii (which is defined as any scalar that is smaller that or equal the positive distance).

The smallest signed distance between the point $p$ and the nearest surface point is equal to the distance between $p$ and the nearest sphere minus its radius.

If the distance is smaller than the radius, then the signed distance will be negative, telling us that the point $p$ is inside of the spheres, and that's why we don't append it. Moreover, the radius of the sphere at point $p$ has to be smaller than the positive distance so as not to intersect the other circle.

To find the smallest signed distance, we loop over the point and radii lists and reassign an initially infinity float parameter if the current signed distance is smaller than the value of the parameter. This is is the equivalent to a KD Tree search except we are subtracting some value defined as the radius.

Next, we create a loop that has an arbitrary number of iterations controlling the maximum number of spheres. However, it does not strictly define the number of spheres itself! The loop has two main parameters: (1) a vector list that will include the spheres locations and (2) a float list that will contain the radii locations. Both inputs are undefined, meaning that they are initially empty lists that we will append to later. In this loop, we generate a random point (we will talk about that algorithm later on), compute the smallest signed distance using the loop we created before and append the sphere location if it is positive. The append condition is implemented as a form of reassign condition for both lists. It is important that we copy the lists at each iteration, ensuring the append doesn't overwrite the original list rendering our reassign condition useless. I chose to define the radius as the positive distance bounded by some arbitrary constant called the Max Radius, though any other positive value less than the distance will work.

Source Link
Omar Emara
  • 22.7k
  • 5
  • 57
  • 104

By looking at the gif above, we will divide our implementation into two parts:

  • Sphere Packing, where we try to find a list of locations and radii for the sphere such that they are non intersecting and look packed.
  • Generating Spirals, this part is relatively easy, all we have to do is find a parametric equation for the spiral over the spheres and replicate it over the list of locations and radii we have got.

#Sphere Packing

There are multiple algorithm which we can use to generate such point locations and radii. Some of which are iterative, other that are generative but expensive and others that are "approximative". We don't really care about execution time because the output is readily cached. Perfect packing is not needed as well because smaller circles will nearly never be seen. From that, we are going to construct a simple algorithm to generate the spheres locations and radii.

Our algorithms will be as follows:

  • Initialize an empty vector and float lists for locations and radii.
  • Define a function that generates a random location, preferably uniform in density.
  • For some arbitrary amount:
  • Generate a random point $p$.
  • Loop over the point and radii lists and compute the smallest signed distance between the point $p$ and the nearest sphere surface point.
  • If the signed distance is positive, that is, the point is outside all of the existing spheres, append the point $p$ and and the radii which is defined as any scalar that is smaller that or equal the positive distance.
  • End loop.

The smallest signed distance between the point $p$ and the nearest surface point is equal to the distance between $p$ and the nearest sphere minus its radius. This can be illustarted by looking at this simple diagram:

Signed Distance

If the distance is smaller than the radius, then the signed distance will be negative, telling us that the point $p$ is inside of the spheres, and that's why we don't append it. Moreover, the radius of the sphere at point $p$ has to be smaller that the positive distance so as not to intersect the other circle.

The implementation is simple, to find the smallest signed distance, we loop over the point and radii lists and reassign an initially infinity float parameter if the current signed distance is smaller than the value of the parameter. This is is the equivalent of a KD Tree search except we are subtracting some value defined as the radius. The implementation is as follows:

Smallest Signed Distance

The rest of the implementation is easy. We create a loop that have an arbitrary number of iterations controlling the maximum possible amount of spheres, however, it does not strictly define the amount itself ! The loop has two main parameters, a vector list that will include the spheres locations and a float list that will contain the radii locations, both inputs are not defined, meaning that they are initially empty lists that we will append to later. In this loop, we generate a random point (We will talk about that algorithm later on), compute the smallest signed distance using the loop we created before and append the sphere location if and only if it is positive. The append condition is implemented as a form of reassign condition for both lists, it is important that we inforce copying the lists at each iteration thus making sure the append doesn't overwrite the original list rendering our reassign condition useless. I chose to define the radius as the positive distance bounded by some arbitrary constant called the Max Radius, though any other positive value less than the distance will work. The implementation is as follows:

Radii

Again, the random point generation is a choice and it may vary based on our needs. I can see that in the reference gif, the random points are uniformly distributed inside a circle, so our random generator can be created as define in the document about Disk Point Picking, that is, the random point is defined by the parametric equation:

$$ \begin{aligned} x &= \sqrt{r} \cos t\\ y &= \sqrt{r} \sin t \end{aligned} $$

Where $r$ and $t$ are uniform random variables, $t$ ranging from zero to two $\pi$ and $r$ ranging from zero to some max radius. Th result would be something like this:

Colored Balls

Had I used a normalized random vector, it would have been like this:

Colored Balls On A Ball

Spiral

All we have to do now is generate a spiral on those spheres. A possible parametric equation would be the ones described in this question and answers, that is:

$$ \begin{aligned} x &= \sqrt{1-t^2}\cos (a \pi t)\\ y &= \sqrt{1-t^2}\sin (a \pi t)\\ z &= t \end{aligned} $$

Where $t$ ranges between negative one and one and $a$ controls the number of revolutions. Which results:

Spiral

But since sin and cos and periodic, we can animate them by adding a phase shift:

Spiral Phase Shift

We can now transform this by some transformation matrix defined by the sphere locations and radii. Create a spline from it. And we are going to put that in a group to be able to use it easily.

Final Implementation

By looping over spheres, randomizing some of the parameters and transforming, as follows:

Splines

We get:

Result

You can now render this as you wish. Maybe through in some random colors or make it particles like the reference gif.

Blend File: