Алгоритм Де Кастельжо
В математической области численного анализа алгоритм Де Кастельжо представляет собой рекурсивный метод оценки полиномов в форме Бернштейна или кривых Безье , названный в честь его изобретателя Поля де Кастельжо . Алгоритм Де Кастельжо также можно использовать для разделения одной кривой Безье на две кривые Безье при произвольном значении параметра.
Хотя алгоритм работает медленнее для большинства архитектур по сравнению с прямым подходом, он более стабилен в числовом отношении . [ нужна ссылка ]
Определение
[ редактировать ]Кривая Безье (степени , с контрольными точками ) можно записать в форме Бернштейна следующим образом где является базисным полиномом Бернштейна Кривая в точке можно оценить с помощью рекуррентного соотношения
Затем оценка в точку можно оценить в операции. Результат дается
Более того, кривая Безье можно разделить в точке на две кривые с соответствующими контрольными точками:
Геометрическая интерпретация
[ редактировать ]Геометрическая интерпретация алгоритма Де Кастельжо проста.
- Рассмотрим кривую Безье с контрольными точками . Соединяя последовательные точки, мы создаем контрольный многоугольник кривой.
- Разделите теперь каждый сегмент этой многоугольника с соотношением и соедините полученные точки. Таким образом, вы получите новый многоугольник, имеющий на один сегмент меньше.
- Повторяйте процесс, пока не дойдете до единственной точки – это точка кривой, соответствующая параметру. .
На следующем рисунке показан этот процесс для кубической кривой Безье:
Обратите внимание, что построенные промежуточные точки на самом деле являются контрольными точками для двух новых кривых Безье, обе точно совпадающих со старой. Этот алгоритм не только оценивает кривую при , но разбивает кривую на две части в точке и предоставляет уравнения двух подкривых в форме Безье.
Приведенная выше интерпретация справедлива для нерациональной кривой Безье. Чтобы оценить рациональную кривую Безье в , мы можем спроецировать эту точку на ; например, трехмерная кривая может иметь свои контрольные точки и веса проецируется на взвешенные контрольные точки . Затем алгоритм действует как обычно, интерполируя . Полученные четырехмерные точки можно спроецировать обратно в трехмерное пространство с разделением перспективы .
В общем, операции над рациональной кривой (или поверхностью) эквивалентны операциям над нерациональной кривой в проективном пространстве . Такое представление в виде «взвешенных контрольных точек» и весов часто удобно при оценке рациональных кривых.
Обозначения
[ редактировать ]При выполнении расчета вручную полезно записать коэффициенты в схеме треугольника в виде Выбирая точку 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];
}
Следующая функция применяет алгоритм Де Кастельжо к массиву points
, разрешая конечную среднюю точку с дополнительными свойствами in
и out
(для касательных «входа» и «выхода» средней точки соответственно).
function deCasteljau(points, position = 0.5) {
let a, b, midpoints = [];
while (points.length > 1) {
const num = points.length - 1;
for (let i = 0; i < num; ++i) {
a = points[i];
b = points[i+1];
midpoints.push([
a[0] + ((b[0] - a[0]) * position),
a[1] + ((b[1] - a[1]) * position),
]);
}
points = midpoints;
midpoints = [];
}
return Object.assign(points[0], {in: a, out: b});
}
В следующем примере эта функция вызывается с помощью зеленые точки внизу, ровно на середине кривой. Полученные координаты должны быть равны , или положение самого центрального красная точка.

{
/* Definition of deCasteljau() function omitted for brevity */
const nodes = window.document.querySelectorAll("circle.n0-point");
const points = Array.from(nodes).map(({cx, cy}) => [cx.baseVal.value, cy.baseVal.value]);
deCasteljau(points); // Result: [192, 32]
}
См. также
[ редактировать ]- Кривые Безье
- Алгоритм Де Бура
- Схема Хорнера для оценки полиномов в мономиальной форме
- Алгоритм Кленшоу для вычисления полиномов в форме Чебышева
Ссылки
[ редактировать ]- Фарин, Джеральд Э.; Хансфорд, Дайанна (2000). Основы CAGD . Натик, Массачусетс: АК Питерс. ISBN 978-1-56881-123-9 .
Внешние ссылки
[ редактировать ]- Кусочно-линейная аппроксимация кривых Безье - описание алгоритма Де Кастельжо, включая критерий определения момента остановки рекурсии
- Кривые Безье и Пикассо — Описание и иллюстрация алгоритма Де Кастельжо, примененного к кубическим кривым Безье.
- Алгоритм де Кастельжо — помощь по реализации и интерактивная демонстрация алгоритма.