Summary

Cushion plants

Demo-file: Demo4.pov

For the construction of our cushion plant we will use positions randomly distributed within an object again. But this time the object won't be a sphere, only a spherical bowl. Actually our sphere_sweeps will be constructed from 5 such bowls which are situated above each other. The sphere_sweeps will be initiated at the outermost bowl and continued by searching the closest position from the respective smaller bowl until reaching the very center of the bowls. The following figures show two of such bowls (left), these bowls and one sphere_sweep (defined by positions from 5 bowls, center) and the whole formation with all possible sphere_sweeps for all positions from the outermost bowl (right). Below these images, the finished cushion plant is shown. This model is certainly not perfect. There are too many branches at many positions, and the inner branches are not as uniform as they should be since we used a cubic and not a linear spline. Nevertheless, the branching is not bad either, and the example demonstrates what can be done with a few positions and sphere_sweep.

random bowls random bowls and on sphere_sweep random bowls and many sphere_sweeps a cushion plant

The demonstration of the code behind this model is started with the definition of a bowl and with the application of a macro that was already introduced in the previous chapter. A macro that is defining random positions within an object and stores these positions in an array.

//First a bowl is defined.

#declare Bowl1 = difference {
sphere { <0, 0, 0>, 1.5 }
sphere { <0, 0, 0>, 1.0 }
}

//And then a suitable macro is used to fill this bowl with positions.

xyzDistributionInsideArray (Bowl1, <-2, 0, -2>, 6, 4, 6, 0.75, 0.75, 0.75, 0.3)

This code only defines the innermost bowl of our example. The other bowls are defined in a very similar way. The parameters of the respective macros should be fitted for all these different bowls, to make sure that the macros really fill up the complete objects. Because we are using this procedure repeatedly, we have to rename the output variables of the macro.

#declare Sum1 = Sum;
#declare Positions1 = array[Sum1];
#declare Positions1 = Positions;

Now we have to select positions from the various bowls for our individual sphere_sweeps. As so many times before, we will store these points in an array before painting the actual sweeps. This time this array will have 8 elements (5 positions from the 5 different bowls, the origin and two outer positions which are not included in the drawing).

#declare SweepPositions = array [8];

We will start the construction of each sphere_sweep at one position from the outermost bowl (here specified by the first element from the respective array "Positions5").

#declare PEnd = Positions5 [0];

While this is one end of the sphere_sweep, the origin is another. In addition there are the two additional points which make not part of the real object.

#declare SweepPositions[0] = <0, -0.5, 0>;
#declare SweepPositions[1] = <0, 0, 0>;
#declare SweepPositions[6] = PEnd;
#declare SweepPositions[7] = PEnd + (1/10*PEnd);

To find the positions from the other bowls, we start at the outer position (PEnd, which is a position in bowl5) and we try to find the closest position to this point in bowl4. This position then becomes part of our array for the sphere_sweep and is used to look for the closest position in bowl3 (etc...)

//First some variables are defined: POpt is used to store the searched positions, PStart is the position from the bowl above,
//for which the closest position in the next bowl should be found and Distance will store the distance between the positions
//from the two bowls.


#declare POpt = <0, 0, 0>;
#declare PStart = PEnd;
#declare Distance = 4;
#declare ticker2 = 0;

//This loop is looking for the position from bowl4 with the closest distance to the given position from bowl5.

#while (ticker2 <Sum4)
#declare PTest = Positions4[ticker2];
#if (vlength(PStart-PTest) < Distance)
#declare POpt = PTest;
#declare Distance = vlength(PStart-PTest);
#else
#end
#declare ticker2 = ticker2 + 1;
#end

//Finally the position found is stored in the array for the sphere_sweep.

#declare SweepPositions[5] = POpt;

Once, we have declared all Positions from the array SweepPositions this way, we can paint the sphere_sweep the usual way. In this case, however, we have included an algorithm resulting in a continous decrease of the sphere_sweep radius.
So far, we only have constructed one sphere_sweep. By repeating the whole process for every position from bowl5, we can paint a branched spherical structure, with branches ending in every position from bowl5:

Summary