我正在为道路网络编写渲染器,它基于RoadXML格式。
此格式的道路曲线有四种类型:
我最后一个问题。
Clothoid与Euler螺旋和Cornu螺旋相同。在RoadXML中,布料弧由三个参数给出:
对于弧三角测量,我需要一个像foo(t)这样的函数,它返回(x,y)坐标为t = 0..length。我为圆弧创建了类似的方法没有问题,但我不能用于布料弧。
部分问题在于我并不完全了解如何在标准回旋公式中应用起点和终点曲率参数。
例如,样本RoadXML道路。 RoadXML sample http://img560.imageshack.us/img560/8172/bigroandabout.png
这是红色椭圆中的布料曲线项。这是参数:
我不知道如何实现这些参数,因为从0到-0.0165的回旋曲率非常直。
如果你给我一个这个函数的代码(用C ++,C#,Java,Python或伪代码)或者只是一个我可以编码的公式,我会很高兴。
这是我的方程式:
x(t) ≈ t,
y(t) ≈ (t^3) / 6,
where length = t = s = curvature.
x(-0.0165) = -0.0165,
y(-0.0165) = -7.48688E-07.
Clotho length = 0.0165,
Source length = 45.185.
Scaled coords:
x'(l) = x / clotho_length * source_length = 45.185,
y'(l) = y / clotho_length * source_length = 5.58149E-07 ≈ 0.
x'(0) = 0,
y'(0) = 0.
因此我得到(0,0)......(45,0)点,这是非常直的。
我的错误在哪里?我做错了什么?
答案 0 :(得分:2)
见论文The Clothoid, by Ryan Seng and Molly Severdia。通常,回旋体由菲涅耳积分定义。事实证明,一个回旋曲C(t)
有一个arclength t
。因此,一般曲线的公式用arclength表示。特定曲线只是一般螺旋的一个子部分,从起始曲率到结束曲率。你必须为一般情况进行轮换和翻译。
答案 1 :(得分:2)
我们来看看。您的数据是:
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
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 !! )
(注意:我在这里称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 )
其中C(t)
和S(t)
为Fresnel integrals。
所以这就是你如何进行缩放。不仅是t = s
,还有 t = s/a
= sqrt(theta)
。在这里,对于终点,t_c = sqrt( k_c s_c / 2) = sqrt( 0.0165407 * 45.185 / 2) = 0.6113066
。
现在,WolframAlpha says,{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使用definition scaled with the additional Sqrt[pi/2]
factor。)
使用您的功能进行测试, x
~= t --> a*(s/a)
= 45.185
, y
~= t^3/3 --> a*(s/a)^3/3 = 73.915445 * 0.6113066^3 / 3
= 5.628481
(原文如此!/3
而不是/6
,您有错误)。
所以你看,使用菲涅耳积分的泰勒级数表示的第一项是不够的 - 到目前为止。您必须使用更多,并且仅在达到所需精度时停止(即,当最后计算的术语小于您预设的精确度值时)。
注意,如果您只是为一次性缩放回旋计算实现一般菲涅耳积分函数,那么当您将结果乘以a
(在订单上)时,您将失去额外的精度通常,对于公路和铁路,10 2 ... 10 3 。