anslo
3 min readMay 18, 2023

--

Hey, thanks for the kind words! I'll answer what I can here - I'm still hoping to write full articles to explain everything eventually, but that may be a few weeks yet...

1. The starting point beings at 0,0 and randomly moves in +x +y until it finds a point that's at least 20m above sea level. Then it tries generating the road, which leads into question 2:

2. For choosing the starting direction, the intelligent thing would be to assess the gradient to start off going level, but right now it just attempts to generate the road starting from angle 0. If it fails to generate (e.g. angle 0 leads directly into a cliff), it'll keep trying new angles until it's done a full revolution, at which point it'll try to find a new start point. I should really improve that... it still often fails completely.

3. The gradient check is also quite basic - I test the gradient in two directions around the vehicle (longitudinal and lateral - testing the height at 4 points in an X shape) and use that as a vague estimation of the direction of the slope. It isn't very accurate, but it's very efficient.

4. The self-intersection problem was the hardest thing to solve, and really deserves its own write-up to properly explain. The important things are to have the road "want" to always move in one direction (e.g. "north") so that it's unlikely to ever double-back on itself; to assess how much the road turns over a certain distance to minimise the chance of turning beyond 270 degrees in a short space; and to assess the chance that a self-intersection might happen. If a self-intersection is detected, the midline resets to an earlier point and tries moving in a different direction, hopefully to avoid whatever piece of land caused the self-intersection.

5. Without smoothing, the road can be quite bumpy, so I process the midline with a smoothing window. The final elevation of each midline node is calculated as the average of the elevation of the 4 neighbouring nodes on either side (for a window size of 9).

6. In this context it's helpful to have a coarse (memory-light) representation of the road because we want to generate it many miles into the distance. Generating the road as a spline is good for that - you only need to generate the sparse control points, and can interpolate the finer points only when you need them (i.e. when the car gets close and you need the detail). Bezier curves might not be the best for this, but I liked how simple they are to work with. Every pair of nodes defines a quadratic Bezier curve, with the control point projected between them. Because of the way the road is generated, the control point is always aligned with the tangent of the road at those nodes, so the result is nice and smooth (only in the x/z plane, though - it isn't smooth in height, and you can sometimes see the sharp change in steepness when driving at night). Then it's quite simple to interpolate the smooth points between using bezier interpolation.

Hopefully that answers the main questions - I'll try to keep working on the big write-up if I can find the time!

--

--

anslo
anslo

Written by anslo

Creative developer lost in the space between design and computer science.

No responses yet