Длина дуги кривой Безье


У меня есть некоторый код, который вычисляет длину кривых Безье. Я пытаюсь написать модульные тесты для него. Но кроме тривиальных случаев (прямая линия Безье)я не знаю никаких фактических правильных значений для длин. Я искал в интернете и не смог найти ни одного.

Есть ли у кого-нибудь эта информация? Я ищу ссылку на таблицу с несколькими строками, содержащими четыре контрольные точки Безье, а затем длину, или, возможно, создать пару Безье в программе рисования, которая вычисляет длина (я пробовал использовать blender и inkscape, чтобы получить эту информацию, и они довольно сложны).

Решение. загрузите код pomax bezier javascript из здесь, а затем откройте этот html в веб-браузере:

<html>
<head>
<script src="bezier.js"></script>
</head>
<body>
<script>
curve = new Bezier([4.0, 0.0,  4.0, 
                    4.0, 0.0,  12.0,
                   16.0, 0.0,  12.0,
                   16.0, 0.0,  4.0]);

document.write(curve.length());
</script>
</body>
</html>
4 3

4 ответа:

Если вы хотите фактические длины дуг для проверки, реализуйте https://github.com/Pomax/bezierjs/blob/gh-pages/lib/bezier.js#L602-604 - это даст вам произвольно точные числа, основанные наквадратуре Лежандра-Гаусса эвалутации (вам не нужно понимать, как это работает, хотя видеосвязь показывает вам, что на самом деле это до смешного просто. Следовательно, реализовать его действительно легко).

Другой вариант-полагаться на что-то вроде wolframalpha.com или Mathematica (, которая бесплатна, если у вас есть Raspberri PI): Установите случайную кривую и заставьте их вычислить длину "правильно", а затем используйте этот результат в качестве эталонного значения в ваших модульных тестах.

Для модульного тестирования кодов можно попробовать следующее:

1) разбить кривую Безье на несколько кривых Безье с помощью алгоритма де Кастельжау
2) вычислите длину дуги для каждой из этих кривых Безье, а затем вычислите их сумму.
3) вычислите длину дуги для исходной кривой Безье.
4) сравните результат от шага 2 и 3. Они должны отличаться только очень маленькой числовой ошибкой, если ваши коды верны.

Еще один способ проверить длину дуги-проверить, если он всегда находится между двумя значениями, вычисленными ниже:

1) выберем несколько точек (скажем, 100) из кривой Безье и вычислим длину полигона из выбранных точек. Это значение всегда будет меньше фактической длины дуги кривой.
2) вычислить длину контрольного полигона. Это всегда будет больше, чем фактическая длина дуги кривой.

Вы можете получить некоторые значения, повозившись с виджетами js на этой странице http://pomax.github.io/bezierinfo/#arclengthapprox

Осознайте, что это старый вопрос, но другим решением является использование элемента пути SVG и метода getTotalLength. Никаких библиотек или сложных уравнений не требуется, пусть браузер делает тяжелую работу.

В самом простом виде:

var a = {x: 0, y: 0},  // from
    b = {x: 4, y: 4},  // to
    c1 = {x: 2, y: 0}, // curve 1
    c2 = {x: 2, y: 4}, // curve 2

    // output the curve in SVG bezier syntax
    svgBezier = `M${a.x} ${a.y} C ${c1.x} ${c1.y}, ${c2.x} ${c2.y}, ${b.x} ${b.y}`,

    // create a new <path> element
    path = document.createElementNS("http://www.w3.org/2000/svg", "path");

// add the curve
path.setAttribute('d', svgBezier);

// get the length using browser power
console.log(path.getTotalLength());  // 5.981128692626953

Примечание: вышеизложенное возвращает надежные результаты в chrome и safari .. firefox кажется менее надежным из коробки