We implemented a 3D stochastic L-System procedural roller coaster as a Blender addon. The addon lets the user choose the number of iterations of the L-System and toggle the realistic twisting of the tracks. In addition to that there is a button that performs the next iteration of the L-System (without having to recompute everything from scratch).
The use of an L-System to build a somewhat realistic roller coaster made us compute a few technical implementations.
Firstly, we obviously needed a L-System, which we originally took from the assignment 8 of the course and translated it in python. To compute it in 3 dimensions, we have implemented different symbols for each possible angle (± vertical and ± horizontal). In addition to that, we needed some symbol to compute the distance that the line will have to travel, depending on the original angles.
Then, we wanted to have a stochastic system, so that we could have different result each time. So we added a parameter to the symbols that give the probability to be chosen at the next iteration (we have to be careful that probabilities sum to 1!). However, not every symbol has to be stochastic (for example angles, fixed lengths, etc), so that we can build predefined rules and have a track that doesn’t get messed up. Those rules are predefined lists of symbols, that are used to have control on the way the L-System evolve. Furthermore, with these rules we can compute some more complex elements such as looping that would be virtually impossible to achieve with only simple rules.
Because the rules where made by us we had complete control over what they had to look like. The main challenge was to start with a track that loops and keep this property after each iteration. This was achieved by designing the rules such that the end point would be at some fixed length in front of the starting point, and the angle at the end point would be constant for these rules. With this, no matter what symbol gets replaced by the stochastic system, the loop property would remain. This rule makes it harder to think about rules that make sense while holding this property but it still was permissive enough such that we could write interesting rules.
The first extension was to randomly place some twists over the circuit. For this we added a new dimension for our points which is the rotation (twist). We then added new symbols that will simply draw a 180° or 360° twist (twisting on the right or the left). Then in Blender we set these twist values to every point. However, we need to keep our loop invariants even throughout rotational degrees (twists) and as it is explained below on Problems encountered, Blender has some problems with that. To deal with it (and to let it possible to have 180° or other angles of rotation - even though to keep it realistic we only kept 180° ones), we added a symbol (called END), that will be the very last part of our loop. This symbol is a long straight line, that will be inversely twisting the track depending on the fourth coordinate value on the starting point of END. With that, our roller coaster will always end with a pretty smooth twist and be rotationally continuous on every iteration.
In the second extension what we wanted was to curve the tracks proportionally to the speed of a wagon that would ride them, to compensate the centrifugal force. In order to achieve this we “simulated” a wagon riding the tracks from start to end and computed the speed using the potential power formula v2 = 2 ⋅ g ⋅ Δh, with Δh being the height difference of the points. By scaling this simulated speed by some amount we then multiplied it to the initial turning angle we computed between the previous position and the the next position. Which gives us the tilting angle of the point. From our testing it looked fairly reasonable even though it’s not the exact physical optimal twist angle. We also had to take into account that we may have random twists, so our algorithm shouldn’t overwrite them. Because this tilting operation happens after we computed the points.
Finally, we decided to add a camera that will follow the path, along with a modeled wagon, to have a nice video. To render the tracks we modeled a small piece of the track that we then repeated a certain number of time to match the length of the curve (using the Array modifier) and then constrained it to follow it (using the Curve modifier).
Figure 1.a: Twists on loopings issue | Figure 1.b: Sharp turn issue | Figure 1.c: Messed up twist issue |
Rule: up then a random part, and back down | Rule: square with random edges |
Rule: fun slope going up, not twisted | Rule: little slope, without random part |
Blue circles are the random parts that will be extended further
Installing our addon the classical way does not seem to work so here’s the procedure that works for us (in Blender 2.79):
If anything goes wrong with the imports, try to open our blender project file “rollercoaster.blend”, reload the text editor view (alt+r) and run it again.
Lucas Strauss (33.33%): mainly worked on the Blender side (addon and render) and the physically based twisting.
Joachim Dunant (33.33%): mainly focused on the rules and probabilities as well as the L-System implementation.
Lucien Iseli (33.33%): mainly worked on the L-System implementation, computing points and stochastic twists.
Each team member worked on every part of the project and helped each other whenever they could.
Blender
to create the track, and to render the final scene.
Python
to code the algorithm for Blender.
Assignment 8 of the course.
https://docs.blender.org/api/2.79/