I like to create trees by calculating the shortest walk from the root to the tips through a set of random points. This works well, but the trees look more like shrubs. There is no central trunk. There are way too many branches. In nature, the amount of branches is kept in check in order to share load and resources.
So, I thought, I could have branches attract each other with Kangaroo. See below with what I came up with. The tree on the right side is the output of Kangaroo. For simplicity, this example is in 2D, although eventually I want to do it in 3D.
I wonder:
Can this be done better?
*Why does the output fail when I increase the strength of the ConstantTension (CT) goal?
In the past, I manually added the trunk. But I want to get away from that. It is easy to end up with a definition with way too many parameters. I donāt want to replicate SpeedTree, which is a nightmare to use due to hundreds of sliders.
One tree I did some years ago, I took the approach of ācumulativeā cross sectional area. That is, ignoring bark, the sum of cross sectional areas of branches going into a node equals the cross sectional area of the trunk supporting that node. My observation from cutting firewood. For illustration, if you made this tree of twisted wire, the trunk would be thick, then each branch would be progressively smaller until the tips, where leaves are, would be a single strand.
Thank you! Some of that looks quite complex. But perhaps I can translate some of these concepts to 2D, which looks easier for prototyping.
I had a similar idea this morning. Thank you for backing it up with a real life observation! The algorithm that I use to design the tree structure makes it straight forward to get this ā in your words ā cumulative cross sectional area. For an example, see my post in the thread: Fast way to pipe polylines? (with varying radius)
Regarding the issue that I raise in our thread here, I wonder how it would look if the length of each branch is defined by the cumulative cross sectional area. Thicker branches can be longer. Kangaroo could be used to find a solution.
See below. I am attempting a new approach, but without success. This time itās not about fusing branches, but about giving branches a more realistic length.
Initially, the tree is built as before. It is pictured on the left side in the screenshot below.
In a next step, the tree is simplified. All kinks are removed, reducing the number of line segments. The result is pictured on the right side.
Each line segment is then weighed based on the number of leaves it connects to the ground. Duplicate line segments are removed.
In the last step, I want to use Kangaroo to pull the vertices with weighed forces along the line segments. But here it fails. Even with a constant force, the output are invalid curves, and I have no idea why:
(ConstantTension goals have quite specific and limited uses - certain types of cable nets and finding Steiner trees. For graphs like this where each internal node has 3 connected edges, the only stable geometry is when the angles between the edges are all 120 degrees. Without additional constraints this typically has to lead to some edges collapsing to zero length)
I realize, I can dial in a non-zero length and get a better effect than when meddling with the strength. I can still make use of the computed weights, i.e. the number of leave connections for each branch segment. They can be used to vary the thickness as shown below and as discussed in a post above.
For finding the initial branch connections for the above tree, I switched from Proximity 2D (Prox) to Delaunay Edges (Con). With Prox I get a nicer initial tree, but for the post processing with Kangaroo that is less relevant. Con is more robust.
Thank you for your suggestions! Those are certainly food for thought.
Regarding your rules:
Only one branching at a time: Enforcing this rule might add a fair bit of realism. However, how to enforce it? A solution might be to write a custom ShortWalk component.
I want to point out that there are many different growth patterns for trees. The Osmanthus trees, which are planted all over the place here, branch with several major branches about one meter above the ground. At first sight, it looks like all the branches emerge from one point, which of course is not true. But they branch very closely.
Largest branch = most branchings / Smallest branch = least branchings: This should already be the case, at least regarding thickness. My definition calculates thickness based on the number of branchings.
Thicker branch is always closest to the ground: Based on my observations, this is generally true, but exceptions are common. Trees do grow new branches in lower positions if there is an incentive to do so.
Maximum branching angle: Iād say generally ShortWalk does a good job at automatically enforcing that. And, trees can decide to grow branches at weird angles. All that matters is reaching sunlight quickly and maintaining structural integrity.
What I want to model in the end are groupings of Chinese banyans where the trunks have fused and the canopy is shared. Find below a simple example with two trees. Compared to my previous example, I removed the Kangaroo component, and I removed the roots below ground. Simplicity is key! Eventually there will be many more trees, and the whole thing will be in 3D. Sill missing are aerial roots, prop roots, and leaves, of course. Yes, the branching looks weird in places, and Iām grateful for any suggestion on how to improve it.
I should have been more explicit. Largest branch = most branchings = closest branching to the ground. I thought maybe the positioning of the text on this schematic:
the indicated branches need to be switched because the thickest branch (being the oldest branch of the treeāthe branch that has had the most time to make further branchings) cannot be at the top!
This logic is easier to enforce if you ensure bifurcation (the only one branching at a time rule)
because that way there is no discrepancy between which branch is highest / lowest. As I wanted to say, but you have already pointed out, even branchings that seem to occur at the same point will actually be branching that occur nearly immeadiately after each other.
Regarding the angles:
Your banching angles are okay until you reach the last tier where they get all wack-a-doodle. This is because you are following an algorithm that attempts to equally distribute the outermost branches along the perimeter of the crown, instead of determining branching angles based upon how far āupā the tree base and closer to the canopy they are.
Iād say, stick to your algorithm (itās easier) and rework the result by coercing unnatural branching angles to closer knots (purple):
If the source code for ShortWalk is available, one could modify it. An idea that comes to mind is to adjust the vertices in the network of curves input: Each time a branch occurs at a vertex, remove it! Or perhaps moving a vertex is better. Otherwise one can end up with a situation where there is no solution.
Actually, the likelihood for bifurcation increases when increasing the density of the network of curves that goes as input into ShortWalk. However, increasing the density also removes the likelihood of overlapping paths. The result looks more like a shrub than a tree. I played with increasing the density closer to the canopy and reducing it near to the trunk. However, it is not that easy to achieve a good effect, and so I might scrap that:
Thanks for your suggestions! Iām not too worried about the twigs at the top, to be honest. Probably, they will hardly visible in the final illustration.
For now, the next steps are going to 3D and adding leaves. Itās all an illusion in the end. And I want to estimate if it is at all possible to prototype growing structures like this with Grasshopper without introducing too much complexity.