回旋曲线的参数化函数

Vla*_*sov 5 math 3d geometry computational-geometry

我正在为道路网络编写渲染器,它基于RoadXML格式。

\n\n

这种格式的道路曲线有四种类型:

\n\n
    \n
  • 部分,
  • \n
  • 圆弧,
  • \n
  • 多段线,
  • \n
  • 布托弧。
  • \n
\n\n

我对最后一个有问题。

\n\n

回旋线与欧拉螺旋、Cornu 螺旋相同。在 RoadXML 中,布料弧由三个参数给出:

\n\n
    \n
  • 开始曲率,
  • \n
  • 末端曲率,
  • \n
  • 长度。
  • \n
\n\n

对于弧三角测量,我需要一个像 foo(t) 这样的函数,它返回 t = 0..length 的 (x, y) 坐标。我为圆弧创建了类似的方法,没有出现任何问题,但我不能为布料弧执行此操作。

\n\n

部分问题是我不完全理解如何在标准回旋曲线公式中应用开始和结束曲率参数。

\n\n

例如,RoadXML 道路示例。\n RoadXML 示例 http://img560.imageshack.us/img560/8172/bigroandabout.png

\n\n

这是红色椭圆中的布料曲线项。其参数:

\n\n
    \n
  • 起始曲率 = 0,
  • \n
  • 末端曲率 = -0.0165407,
  • \n
  • 长度 = 45.185。
  • \n
\n\n

我不知道如何实现这些参数,因为从 0 到 -0.0165 的回旋曲线曲率非常直。

\n\n

如果您给我这个函数的代码(C++、C#、Java、Python 或伪代码)或只是一个我可以编码的公式,我会很高兴。

\n\n

这是我的方程:

\n\n
x(t) \xe2\x89\x88 t,\ny(t) \xe2\x89\x88 (t^3) / 6,\nwhere length = t = s = curvature.\n\nx(-0.0165) = -0.0165,\ny(-0.0165) = -7.48688E-07.\n\nClotho length = 0.0165,\nSource length = 45.185.\n
Run Code Online (Sandbox Code Playgroud)\n\n

缩放坐标:

\n\n
x\'(l) = x / clotho_length * source_length = 45.185,\ny\'(l) = y / clotho_length * source_length = 5.58149E-07 \xe2\x89\x88 0.\n\nx\'(0) = 0,\ny\'(0) = 0.\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此我得到 (0, 0)...(45, 0) 点,这是非常直接的。

\n\n

我的错误在哪里?我究竟做错了什么?

\n

Wil*_*ess 3

让我们来看看。您的数据是:

start curvature = 0,                straight line, R=INF
end curvature = -0.0165407,         circular arc, R_c = 1/k_c = 60.4569335
length = 45.185.                    distance along clothoid, s_c = 45.185
Run Code Online (Sandbox Code Playgroud)

根据维基百科文章

R s = const = R_c s_c                   ( s ~ k = 1/R by definition of clothoid )
d(s) = R d(theta)
d(theta) = k d(s)
d(theta) / d(s) = 1 / R = k = s / R_c s_c  

theta = s^2 / 2 R_c s_c = (s/a)^2 = s / 2 R = k s / 2 
                               where ___________________
                                     a = sqrt(2 R_c s_c)       (... = 73.915445 )
                                     ~~~~~~~~~~~~~~~~~~~
    and so  theta_c = k_c s_c / 2      (... = 0.37369576475 = 21.411190 degrees )
                                                     ( not so flat after all !! )
Run Code Online (Sandbox Code Playgroud)

(注:我a在这里称之为 WP 文章所称的倒数a)。然后,

d(x) = d(s) cos(theta)
d(y) = d(s) sin(theta)

x = INT[s=0..s] cos(theta) d(s) 
  = INT[s=0..s] cos((s/a)^2) a d(s/a) 
  = a INT[u=0..(s/a)] cos(u^2) d(u)   = a C( s/a )

y = a INT[u=0..(s/a)] sin(u^2) d(u)   = a S( s/a )
Run Code Online (Sandbox Code Playgroud)

其中C(t)S(t)菲涅耳积分

就是缩放的方法。不只是t = s,但是。在这里,作为终点,.t = s/a = sqrt(theta)t_c = sqrt( k_c s_c / 2) = sqrt( 0.0165407 * 45.185 / 2) = 0.6113066

现在,WolframAlpha 说{73.915445 Sqrt[pi/2] FresnelC[0.6113066/Sqrt[pi/2]], 73.915445 Sqrt[pi/2] FresnelS[0.6113066/Sqrt[pi/2]]} = {44.5581, 5.57259}(显然 Mathematica 使用的定义是通过附加Sqrt[pi/2]因子缩放的。)

用你的函数测试它,(原文如此!不是,你在那里有一个错误)。x ~= t --> a*(s/a) = 45.185y ~= t^3/3 --> a*(s/a)^3/3 = 73.915445 * 0.6113066^3 / 3 = 5.628481/3/6

所以你看,到目前为止,仅使用菲涅尔积分的泰勒级数表示中的第一项是不够的。您必须使用更多,并且仅在达到所需的精度时才停止(即,当最后计算的项的大小小于您预设的精度值时)。

请注意,如果您只是实现通用菲涅尔积分函数来进行一次性缩放回旋曲线计算,那么当您将结果乘以a(大约为 10 2 ... 10 3通常适用于公路和铁路)。