Алгоритм де Кастельжо
В математической области численного анализа алгоритм Де Кастельжо представляет собой рекурсивный метод оценки полиномов в форме Бернштейна или кривых Безье , названный в честь его изобретателя Поля де Кастельжо . Алгоритм Де Кастельжо также можно использовать для разделения одной кривой Безье на две кривые Безье при произвольном значении параметра.
Хотя для большинства архитектур алгоритм работает медленнее по сравнению с прямым подходом, он более стабилен в числовом отношении . [ нужна ссылка ]
Определение
[ редактировать ]Кривая Безье (степени , с контрольными точками ) можно записать в форме Бернштейна следующим образом где является базисным полиномом Бернштейна Кривая в точке можно оценить с помощью рекуррентного соотношения
Затем оценка в точку можно оценить в операции. Результат дается
Более того, кривая Безье можно разделить в точке на две кривые с соответствующими контрольными точками:
Геометрическая интерпретация
[ редактировать ]Геометрическая интерпретация алгоритма Де Кастельжо проста.
- Рассмотрим кривую Безье с контрольными точками . Соединяя последовательные точки, мы создаем контрольный многоугольник кривой.
- Разделите теперь каждый сегмент этого многоугольника с соотношением и соедините полученные точки. Таким образом, вы получите новый многоугольник, имеющий на один сегмент меньше.
- Повторяйте процесс, пока не дойдете до единственной точки – это точка кривой, соответствующая параметру. .
На следующем рисунке показан этот процесс для кубической кривой Безье:
Обратите внимание, что построенные промежуточные точки на самом деле являются контрольными точками для двух новых кривых Безье, обе точно совпадающих со старой. Этот алгоритм не только оценивает кривую при , но разбивает кривую на две части в точке и предоставляет уравнения двух подкривых в форме Безье.
Приведенная выше интерпретация справедлива для нерациональной кривой Безье. Чтобы оценить рациональную кривую Безье в , мы можем спроецировать эту точку на ; например, трехмерная кривая может иметь свои контрольные точки и веса проецируется на взвешенные контрольные точки . Затем алгоритм действует как обычно, интерполируя . Полученные четырехмерные точки можно спроецировать обратно в трехмерное пространство с разделением перспективы .
В общем, операции над рациональной кривой (или поверхностью) эквивалентны операциям над нерациональной кривой в проективном пространстве . Такое представление в виде «взвешенных контрольных точек» и весов часто бывает удобно при оценке рациональных кривых.
Обозначения
[ редактировать ]При выполнении расчета вручную полезно записать коэффициенты в схеме треугольника в виде Выбирая точку t 0 для оценки многочлена Бернштейна, мы можем использовать две диагонали схемы треугольника, чтобы построить деление многочлена. в и
Кривая Безье
[ редактировать ]
При оценке кривой Безье степени n в 3-мерном пространстве с n + 1 контрольными точками P i с мы разбиваем кривую Безье на три отдельных уравнения которые мы оцениваем индивидуально с помощью алгоритма Де Кастельжо.
Пример
[ редактировать ]Мы хотим оценить полином Бернштейна степени 2 с коэффициентами Бернштейна в точке t 0 .
Мы начинаем рекурсию с и на второй итерации рекурсия останавливается на который является ожидаемым полиномом Бернштейна степени 2 .
Реализации
[ редактировать ]Вот примеры реализации алгоритма Де Кастельжо на различных языках программирования.
Хаскелл
[ редактировать ]deCasteljau :: Double -> [(Double, Double)] -> (Double, Double)
deCasteljau t [b] = b
deCasteljau t coefs = deCasteljau t reduced
where
reduced = zipWith (lerpP t) coefs (tail coefs)
lerpP t (x0, y0) (x1, y1) = (lerp t x0 x1, lerp t y0 y1)
lerp t a b = t * b + (1 - t) * a
Питон
[ редактировать ]def de_casteljau(t: float, coefs: list[float]) -> float:
"""De Casteljau's algorithm."""
beta = coefs.copy() # values in this list are overridden
n = len(beta)
for j in range(1, n):
for k in range(n - j):
beta[k] = beta[k] * (1 - t) + beta[k + 1] * t
return beta[0]
Ява
[ редактировать ]public double deCasteljau(double t, double[] coefficients) {
double[] beta = coefficients;
int n = beta.length;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < (n - i); j++) {
beta[j] = beta[j] * (1 - t) + beta[j + 1] * t;
}
}
return beta[0];
}
Пример кода на Javascript
[ редактировать ]Следующая функция javascript применяет алгоритм Де Кастельжау к массиву контрольных точек или полюсов , первоначально названных Де Кастельжау, чтобы уменьшать их одну за другой до тех пор, пока не будет достигнута точка на кривой для заданного t между 0 для первой точки кривой и 1. для последнего
function crlPtReduceDeCasteljau(points, t) {
let retArr = [ points.slice () ];
while (points.length > 1) {
let midpoints = [];
for (let i = 0; i+1 < points.length; ++i) {
let ax = points[i][0];
let ay = points[i][1];
let bx = points[i+1][0];
let by = points[i+1][1];
// a * (1-t) + b * t = a + (b - a) * t
midpoints.push([
ax + (bx - ax) * t,
ay + (by - ax) * t,
]);
}
retArr.push (midpoints)
points = midpoints;
}
return retArr;
}
Например
var poles = [ [0, 128], [128, 0], [256, 0], [384, 128] ] crlPtReduceDeCasteljau (poles, .5)
возвращает массив
[ [ [0, 128], [128, 0], [256, 0], [384, 128 ] ], [ [64, 64], [192, 0], [320, 64] ], [ [128, 32], [256, 32]], [ [192, 32]], ]
Какие точки и соединяющие их отрезки показаны ниже?

См. также
[ редактировать ]- Кривые Безье
- Алгоритм Де Бура
- Схема Хорнера для оценки полиномов в мономиальной форме
- Алгоритм Кленшоу для вычисления полиномов в форме Чебышева
Ссылки
[ редактировать ]- Фарин, Джеральд Э.; Хансфорд, Дайанна (2000). Основы CAGD . Натик, Массачусетс: АК Питерс. ISBN 978-1-56881-123-9 .
Внешние ссылки
[ редактировать ]- Кусочно-линейная аппроксимация кривых Безье - описание алгоритма Де Кастельжо, включая критерий определения момента остановки рекурсии
- Кривые Безье и Пикассо — Описание и иллюстрация алгоритма Де Кастельжо, примененного к кубическим кривым Безье.
- Алгоритм де Кастельжо — помощь по реализации и интерактивная демонстрация алгоритма.