В математической области численного анализа алгоритм Де Кастельжо представляет собой рекурсивный метод оценки полиномов в форме Бернштейна или кривых Безье , названный в честь его изобретателя Поля де Кастельжо . Алгоритм Де Кастельжо также можно использовать для разделения одной кривой Безье на две кривые Безье при произвольном значении параметра.
Затем оценку в точке можно оценить в операциях. Результат дается
Более того, кривую Безье можно разбить в точке на две кривые с соответствующими контрольными точками:
Геометрическая интерпретация
Геометрическая интерпретация алгоритма Де Кастельжо проста.
Рассмотрим кривую Безье с контрольными точками . Соединяя последовательные точки, мы создаем контрольный многоугольник кривой.
Разделите теперь каждый сегмент линии этого многоугольника с соотношением и соедините полученные точки. Таким образом, вы получите новый многоугольник, имеющий на один сегмент меньше.
Повторяйте процесс, пока не дойдете до единственной точки – это точка кривой, соответствующая параметру .
На следующем рисунке показан этот процесс для кубической кривой Безье:
Обратите внимание, что построенные промежуточные точки на самом деле являются контрольными точками для двух новых кривых Безье, обе точно совпадающих со старой. Этот алгоритм не только оценивает кривую при , но и разбивает кривую на две части при и предоставляет уравнения двух подкривых в форме Безье.
Приведенная выше интерпретация справедлива для нерациональной кривой Безье. Чтобы оценить рациональную кривую Безье в , мы можем спроецировать точку в ; например, трехмерная кривая может иметь контрольные точки и веса , проецируемые на взвешенные контрольные точки . Затем алгоритм работает как обычно, интерполируя в . Полученные четырехмерные точки могут быть спроецированы обратно в трехмерное пространство с разделением перспективы .
В общем, операции над рациональной кривой (или поверхностью) эквивалентны операциям над нерациональной кривой в проективном пространстве . Такое представление в виде «взвешенных контрольных точек» и весов часто удобно при оценке рациональных кривых.
Обозначения
При выполнении вычислений вручную полезно записать коэффициенты в схеме треугольника следующим образом.
При выборе точки t 0 для оценки полинома Бернштейна мы можем использовать две диагонали схемы треугольника, чтобы построить деление многочлена
на
и
Кривая Безье
При оценке кривой Безье степени n в трехмерном пространстве с n + 1 контрольными точками Pi
мы
разбиваем кривую Безье на три отдельных уравнения , которые мы оцениваем индивидуально ,
используя алгоритм Де Кастельжо.
Пример
Мы хотим оценить полином Бернштейна степени 2 с коэффициентами Бернштейна
в точке t 0 .
Мы начинаем рекурсию с
и на второй итерации рекурсия останавливается на
ожидаемом полиноме Бернштейна степени 2 .
Реализации
Вот примеры реализации алгоритма Де Кастельжо на различных языках программирования.
Хаскелл
деКастельжау :: Двойной -> [( Двойной , Двойной )] -> ( Двойной , Двойной )деКастельжо т [ б ] = бdeCasteljau t coefs = deCasteljau t уменьшенныйгдеуменьшенный = zipWith ( lerpP t ) коэфы ( хвостовые коэфы )lerpP t ( x0 , y0 ) ( x1 , y1 ) = ( lerp t x0 x1 , lerp t y0 y1 )lerp т а б знак равно т * б + ( 1 - т ) * а
Питон
def de_casteljau ( t : float , coefs : list [ float ]) -> float :"""Алгоритм Де Кастельжо."""бета = коэф . copy () # значения в этом списке переопределяютсяn = len ( бета )для j в диапазоне ( 1 , n ):для k в диапазоне ( n - j ):бета [ k ] = бета [ k ] * ( 1 - t ) + бета [ k + 1 ] * tвернуть бета [ 0 ]
Джава
public double deCasteljau ( двойной t , двойной [] коэффициенты ) {двойной [] бета = коэффициенты ;int n = бета . длина ;для ( int я знак равно 1 ; я <= n ; я ++ ) {для ( int j знак равно 0 ; j < ( n - я ); j ++ ) {бета [ j ] = бета [ j ] * ( 1 - т ) + бета [ j + 1 ] * т ;}}вернуть бета [ 0 ] ;}
JavaScript
Следующая функция применяет алгоритм Де Кастельжо к массиву points, определяя конечную среднюю точку с дополнительными свойствами inи out(для касательных «входа» и «выхода» средней точки соответственно).
функция де Кастельжау ( точки , позиция = 0,5 ) {пусть a , b , средние точки = [];в то время как ( точки . длина > 1 ) {const num = очки . длина - 1 ;для ( пусть я знак равно 0 ; я < число ; ++ я ) {а = точки [ я ];б = баллы [ я + 1 ];средние точки . толкать ([a [ 0 ] + (( b [ 0 ] - a [ 0 ]) * позиция ),a [ 1 ] + (( b [ 1 ] - a [ 1 ]) * позиция ),]);}точки = средние точки ;средние точки = [];}вернуть Объект . назначить ( точки [ 0 ], { in : a , out : b });}
В следующем примере эта функция вызывается с зелеными точками внизу, ровно на середине кривой. Полученные координаты должны равняться или положению самой центральной красной точки.
{ /* Определение функции deCasteljau() опущено для краткости */ const nodes = window . документ . querySelectorAll ( "circle.n0-point" ); константные точки = Массив . из ( узлов ). карта (({ cx , cy }) => [ cx .baseVal . value , cy . baseVal . value ]) ; де Кастельжо ( очки ); // Результат: [192, 32] }