arrow_back Back home
26 December 2023

Forest generation

I’m interested in modeling how plants grow together. With an accurate model, I can eventually teach computers to care for plants as well as any human can– to give robots a digital “green thumb.” That’s the idea, anyway.

As an early step, here’s a forest growth simulator that I’ve cooked up in Typescript with the help of three.js. The forest is specifically an Appalachian oak forest, which is what Carnegie Mellon’s campus used to be covered in. I’ve included three major forest layers, from the understory to the canopy to the emergent (topmost) layer.

I’ve included two understory species: Amelanchier arborea (common serviceberry) and Nyssa sylvatica (black tupelo).

The canopy includes four species: Acer rubrum (red maple), Carya ovata (shagbark hickory), Quercus montana (chestnut oak) and Quercus rubra (northern red oak).

I’ve added a single species in the emergent layer, Liriodendron tulipifera (tulip tree), one of the tallest native trees in North America.

View it fullscreen here. View source code here.

Generation technique

Trees are generated by randomly selecting planting locations. If the planting location is too close to existing trees, then that location is skipped. “Too close” is based on the size and forest layer of the tree that we’re trying to plant, as well as the size and layer of the nearby trees. That means that small, understory species can be planted closely to large, emergent layer trees, but two large tulip trees must be spaced further apart.

In the future, I’d like to account for estimated wind exposure and soil moisture as a function of elevation. That’s why I generated hills. However, I was not able to find a straightforward function to express individual species’ tolerances with respect to elevation.

CO2 estimation methodology

I used a back-of-the-napkin approximation 10kg of CO2 sequestered per tree per year, which is far more conservative than the typical (and likely inflated) 22kg figure, following guidance from OneTreePlanted. This organization in turn drew from the Global Removals Database, which used the methodology from Bernal, Murray, et al.. Of course, sequestered CO2 actually depends on the tree’s age, diameter, height, planting density, and so on. We’re trying to estimate the volume of each tree’s wood and its wood density, which in turn gives us the wood’s mass, which is finally related to the mass of CO2.

Acknowledgements

Thanks to Maya Batic for her three.js template code and to georgealways for his lil-gui. The Perlin noise used to generate the terrain elevation map was adapted from code by Joseph Gentle, Stefan Gustavson, and Pter Eastman.