More Randomly Generated Growth Rules

Here are some more plant-shapes that are 'grown' in the same simulation environment, but with different randomly generated growth rules.  Note the variety in shapes! See the previous post for a detailed explanation. I am posting the most interesting structures I have come across, but many of the randomly generated rules result in 'boring' shapes, like a vertical line. Beware my aesthetic bias!

Since the last post I realized why many of the structures grew preferentially in a certain direction. This was because of the primitive functions 'add,' 'multiply,' and 'subtract' that operated element-wise on two vectors. Such element-wise operations are likely two take two vectors and make all there elements more positive, or more negative, or some combination. Because this affects the y-vector of the next node, this has a positive-feedback effect, resulting in structures that grew in one direction. I removed those functions for now.

gnarly-spindly-tree Below is a structure tagged gnarly-spindly-tree (I am using git tags to keep track of interesting structures along the way.) Kinda reminds me of a blue-oak (Quercus douglasii)

This node-edge shape could be thought of as the 'phenotype' in the context of the evolutionary algorithm.

gnarly-tree

Below is the full processor tree for the above structure. This can be thought of as the 'genotype.'

gnarly-genome

Here is a close up of the processor tree 'genotype.'

close_up

I have added some more primitive functions since the last post, like cross product for vectors, extracting the x, y, z component, and finding the angle between vectors.

Here are some more fun shapes!

shagy-wild-bush. For this one the processor tree is so huge its not very informative to look at.

shaggy

straight-segment-bush I like how simple this processor tree is, but still leads to an interesting growth shape. I probably would not have come up with this myself. Since the processor tree is simple enough to evaluate yourself, I'll explain its parts: x and y are vectors (see prev. post for description of what they are). Norm( vec ) outputs the length of the input vector. Rotate_vec_np( vec1, vec2, angle ) rotates the first vector about the second vector, by some angle in radians (c1=.5 in this case). If_greater( arg1, arg2, arg3, arg4 ) outputs arg3 if arg1 is greater than arg 2, otherwise it returns arg4. Thats it!

straight_segment_bush

No-Name Alas, the below structure was generated before I created a system for saving and 'resurrecting' processor trees.

no_name_tall

A note on how I save the processor trees: I mentioned above that I am using a git tag to save out interesting shapes. In the past when working on generative projects like this coral one,  I tried to save out lists of parameters with a given shape. The problem with this is that as soon as I changed the code and added new parameters or completely different behavior, those parameter lists were useless! This time around I realized that that the entire code base of the project at the time the form is generated is the 'DNA' of a given shape. So really the best way to save that information is using git, a version control system for keeping track of code. I started the practice of committing all relevant code after an interesting shape was found, and then immediately using  ' git tag some-descriptive-name ' to associate that tag with a certain shape. That worked well until I started messing around with the randomly generated programs I have been referring to as 'processor trees.' To save these I have the script save a .txt file which contains a text representation of the processor tree. For example straight-segment-bush uses this processor tree:

if_greater(norm(x), norm(y), rotate_vec_np(x, y, c1), y)

If the structure is one I want to save, I copy the file and rename it, and I create a git tag of the same name. That way if I change the primitive set of functions that the processor tree uses, I can still go back to the version of the code where the primitive set was correctly configured for that processor tree. In this case I use

git checkout refs/tags/tag-name

To re-enstate the code. Finally, there is a function in the deap.gp library that can recreate the working processor tree from the text-based representation. That's how I can resurrect an extinct virtual organism!

Written on December 21, 2016