任何道路背后的简单几何原理
The simple geometry behind any road

原始链接: https://sandboxspirit.com/blog/simple-geometry-of-roads/

## 程序化道路生成:连接曲线 本文详细介绍了生成平滑、逼真道路背后的核心几何原理。其基础在于“剖面”——道路的抽象横截面,充当控制点,类似于贝塞尔曲线。这些剖面定义了道路*如何*弯曲,而不是定义整个道路形状。 挑战在于仅使用直线和圆弧平滑地连接这些剖面。解决方案利用“圆角”构造:从每个剖面的端点延伸直线,找到它们的交点,然后用弧线和线段连接。 然而,简单的弧线并不总是足够的,尤其是在道路需要改变方向(“S”形曲线)时。在这种情况下,使用三次埃尔米特样条曲线计算一个中间剖面——一条由起点/终点及其切线定义的平滑曲线——并将其放置在样条曲线的拐点附近。 虽然存在边缘情况,但作者实施了一个设计约束:防止用户创建需要过于复杂解决方案的情况。这确保了鲁棒性。下一步是处理道路交叉口,并将这些构建块拼接成完整的网络。最终,这种方法提供了一个灵活的系统,用于创建多样且可信的道路布局。

对不起。
相关文章

原文

In the last blog post, I explained what sits at the backbone of procedurally generated roads: the data structure, aka the minimum information you need to describe any piece of road infrastructure. The answer to that fundamental question was a set of abstract cross-sections of the road, each storing a snapshot of how the road looks at that specific point (or, should I say, line). I called them simply: profiles.

A good analogy I didn’t have the inspiration to make at the moment was to compare them with Bezier splines. To store a Bezier spline, you don’t need to save the entire curve explicitly, but just anchor points and handle positions. With a bit of math and a few formulas, you can reconstruct the actual path at any time by interpolating between the control points.

The profile-based representation works the same in my system. The profiles are the control information, and the actual geometry defining the road path is the interpolated result of those profiles.

bezier_and_profiles

In this blog post, I’ll go over how I am computing the purple part. How to interpolate between these green profiles to generate beautifully smooth, parallel paths?

The Geometry Problem

In my first post, I explained why I embarked on this journey: I found most game devs seemed to be using the wrong tool for the job, rendering roads by expanding a centerline Bezier spline. I knew from the start I wanted to use only lines and circular arcs to build the actual road shape.

With the prerequisites fixed, we reduced our problem to a geometry one:

Given two profiles at arbitrary positions and orientations, how do we connect their respective endpoints using smooth parallel arcs?

A simple geometric property of circles instantly gets us one simplification for free. Points equally spaced along a radius trace concentric arcs when rotated around the same center. As long as our profiles are equal in length, we only need to solve the path for one pair of corresponding endpoints. Applying the same construction across the profile naturally results in parallel paths.

The problem is then reduced to:

Given two points AA and BB with their respective direction vectors dA\vec{dA}

A Single Arc Won’t Do The Trick

You probably guessed it without jumping into the math. Two arbitrary points, each with a prescribed tangent vector, cannot always be connected by a single circular arc tangent to both vectors. It’s actually more of a special optimal case when they do, meaning the points happen to lie on the same circle.

It might look like we’ve backed ourselves into a corner at this point. Constraints we’ve fixed simply can’t be satisfied. But at the same time, in real life, roads do exist, defined only by arcs and lines. The answer is to ease the constraints a bit by letting each arc also have a line extension until it meets the point along the tangent line.

The Geometrical Solution

Here is how the construction unfolds:

  1. Take two respective endpoints (let’s denote them AA and BB).
  2. From each point, extend a line in the direction the road should continue (perpendicular to the profile). I’ll refer to these as continuation lines.
  3. Let’s call the point where these two lines intersect CC.
  4. We now have two segments, CACA and CBCB, which differ in length in the general case. Let’s assume CBCB is longer than CACA.
  5. Starting from BB and moving along the continuation line toward CC, we pick a new point MM such that CM=CACM = CA
  6. From here, draw a line through MM that is perpendicular to the second continuation line, and a line through AA that is perpendicular to the first.
  7. Let these two perpendiculars intersect at a new point, OO.

solve_diagram

The Tangent–Radius Theorem tells us that a radius is always perpendicular to the tangent at the point of contact. So if OMOM and OAOA are radii of the same circle, it means the circle will be tangent to the continuation lines at MM and AA.

The only thing left to do is prove OM=OAOM = OA

The proof is quite simple. Consider the right-angled triangles OCMOCM and OCAOCA with a common hypotenuse OCOC. Since we chose M so that CM=CACM = CA

The final path is therefore an arc from AA to MM followed by a straight line from MM to BB.

A straight line, then an arc. That’s the whole trick.

Some CAD engineers may read this and chuckle: “That’s just a fillet”. Yes, this thing I’ve just described is nothing new under the sun; it’s called a two-line fillet construction. But with a little twist: one tangential point is always fixed, and the other is solved for. An even more practical way to picture this (especially for people who use tools like Illustrator or Figma) is to think of applying an infinite corner radius to one corner of a shape.

Profiles Interpolation

Now that we have a reliable way to smooth a path between two endpoints with prescribed directions, we can get back to the real problem: connecting a source to a target profile.

In most cases, this is actually very straightforward.

If the two profiles are equal in length and their continuation lines intersect in a reasonable way, then connecting the full profiles is just the same construction applied twice to their corresponding ends. In other words, we solve the same geometry problem on both sides of the road cross-section, and the two edges will run parallel naturally.

So most ordinary road segments boil down to repeating this exact same trick between the start and end profiles. Here is how it unfolds visually:

联系我们 contact @ memedata.com