Параметризованная функция для клотоиды

Я кодирую рендерер для дорожной сети, которая основана на формате RoadXML.

Кривые дороги из этого формата имеют четыре типа:

  • сегмент,
  • дуга окружности,
  • поли линия,
  • дуга клото.

И у меня проблема с последним.

Клотоид - то же самое со спиралью Эйлера и спиралью Корну. В RoadXML дуга клото задается тремя параметрами:

  • начать кривизну,
  • конечная кривизна,
  • длина.

Для триангуляции дуги мне нужна функция типа foo(t), которая возвращает координаты (x, y) для t = 0..length. Я создал подобные методы для дуги окружности без проблем, но я не могу сделать это для дуги клото.

Часть проблемы заключается в том, что я не совсем понимаю, как применять параметры начальной и конечной кривизны в стандартных формулах клотоиды.

Например, образец RoadXML Road. http://img560.imageshack.us/img560/8172/bigroandabout.png

Это элемент кривой клото в красном эллипсе. Это параметры:

  • начальная кривизна = 0,
  • конечная кривизна = -0,0165407,
  • длина = 45,185.

Я не знаю, как реализовать эти параметры, потому что кривизна клотоиды от 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.

Масштабные координаты:

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) баллов, что очень прямолинейно.

Где моя ошибка? Что я делаю неправильно?

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) являются интегралами Френеля.

Так вот, как вы делаете масштабирование. Не просто t = s, но t = s/a= sqrt(theta), Здесь, для конечной точки, t_c = sqrt( k_c s_c / 2) = sqrt( 0.0165407 * 45.185 / 2) = 0.6113066,

Теперь Вольфрам Альфа говорит: {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.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 для автомобильных и железных дорог).

См. Статью "Клотоид" Райана Сенга и Молли Севердиа. Как правило, клотоиды определяются интегралами Френеля. Оказывается, что клотоида C(t) имеет длину t, Таким образом, сразу же формула для общей кривой выражается через длину дуги. Конкретная кривая - это просто часть общей спирали, идущая от начальной кривизны до конечной кривизны. Вы должны сделать ротацию и перевод для общего случая.

Другие вопросы по тегам