2
$\begingroup$

enter image description here

There are 5 cubes at the top and 5 at the bottom (the number may be greater), with splines between them. How can I randomize them?

They must not intersect with each other. They can either stretch forward and backward or curve.

$\endgroup$

1 Answer 1

5
$\begingroup$

There is to parts in this problem.

  1. Connect the positions with splines.
  2. Deintersect the splines. Result result (animated)

Creating the curves

First you need the target positions. The top row has to be shuffled.

target positions

Then the corresponding points' positions can be interpolated.

interpolating

Create the base row of points with the points node. I deleted some to create some random gaps, because it looks good.

points node

Then add some curves with the Curve Line node. I resampled it so that each curve has 50 points. Each point get a custom attribute called factor. (It may be possible to use the spline factor directly though.)

Each instance gets an id (custom attribute) called splineId.

Since the curves have no length yet, you will not see the instances at this point.

create curves

Use the initial points again and offset them to their target positions. The sort elements with a randomized weights shuffles their order.

create target positions

We can use these target positions to interpolate to. The factor for lerping is the $factor$ along each curve. We sample the target position by the $splindId$ index. For the x-axis, I modified the interpolation with a curve to give them some ease. The z-value wouldn't need to change, but for the relaxing of the curves (later), I will give them an initial (very small) random offset.

interpolate between origin and target point

The result is this set of curves.

result

Deintersection

Next, add a Set Curve Radius node, to give the curves some radius.

Relaxing the points involves three steps:

  1. Get the proximity of each point on a spline to their neighbouring splines.
  2. Move the point away from the geometry if the distance is less than their radius (= if they intersect).
  3. Smooth the curve.

Step 2 usually produces unnatural spikes as single points get deintersected. Step 3 usually smooths the curve closer to their original position causing more intersection. That's why these steps 1-3 are repeat for a couple of iterations.

Relaxing: 1. Get the distance

For each point, we need the closest position on any other spline. Here this vector is visualized as well as the distance.

proximity

We use a repeat zone to cycle through each spline. Add a counter to the repeat zone, then split the geometry into the current spline and the others. Convert the others to a mesh and use the Proximity node, set to edges. Finally, store the closest position as a named attribute ($closest$) and join the splines back again.

After this process, each point has a $closest$ vector attribute.

(Sampling multiple closest points on more than one spline is left as an exercise to the reader.)

getting the closest position

Relaxing: 2. Move the points away

For each point, we require a vector pointing from the closest position to the point position. By mapping its length from 0 to $radius$ to $1$ - $0$, we can control how much the point is pushed away. Since we are going to do multiple iterations of steps 1-3 it could also be wise, to not push it away completely.

The amount can be multiplied by some value <1 because not only the active point is moving away, all of the are.

displace closest points

As a result the points are displaced and don't intersect anymore.

intersections are resolved

Relaxing: 3. Smooth the curve

Smoothing can be applied by bluring the position attribute. I use the $factor$ attribute again, to fix the ends of the splines in place.

nodes: smoothing the points

But this cause the splines to intersect again.

the points intersect again

Repeat steps 1-3

By using another repeat zone and doing multiple passes over the relaxing process, the splines gradually become stable.

1, 2 and 20 iterations

If you only want the depth axis to change, you could add a rest position attribute and apply the x and y value of the rest position after each displacement and smoothing step.

preserve rest x, y

$\endgroup$

You must log in to answer this question.