Уравнение кривой безье по точкам

Кривые Безье

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/bezier-curve.

Кривые Безье используются в компьютерной графике для рисования плавных изгибов, в CSS-анимации и много где ещё.

Несмотря на «умное» название – это очень простая штука.

В принципе, можно создавать анимацию и без знания кривых Безье, но стоит один раз изучить эту тему хотя бы для того, чтобы в дальнейшем с комфортом пользоваться этим замечательным инструментом. Тем более что в мире векторной графики и продвинутых анимаций без них никак.

Видео:Минутка науки. Кривая БезьеСкачать

Минутка науки. Кривая Безье

Виды кривых Безье

Кривая Безье задаётся опорными точками.

Их может быть две, три, четыре или больше. Например:

Уравнение кривой безье по точкам

Уравнение кривой безье по точкам

По четырём точкам:

Уравнение кривой безье по точкам

Если вы посмотрите внимательно на эти кривые, то «на глазок» заметите:

Точки не всегда на кривой. Это совершенно нормально, как именно строится кривая мы рассмотрим чуть позже.

Степень кривой равна числу точек минус один. Для двух точек – это линейная кривая (т.е. прямая), для трёх точек – квадратическая кривая (парабола), для четырёх – кубическая.

Кривая всегда находится внутри выпуклой оболочки, образованной опорными точками:

Уравнение кривой безье по точкамУравнение кривой безье по точкам

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

Основная ценность кривых Безье для рисования – в том, что, двигая точки, кривую можно менять, причём кривая при этом меняется интуитивно понятным образом.

Попробуйте двигать точки мышью в примере ниже:

Как можно заметить, кривая натянута по касательным 1 → 2 и 3 → 4.

После небольшой практики становится понятно, как расположить точки, чтобы получить нужную форму. А, соединяя несколько кривых, можно получить практически что угодно.

Вот некоторые примеры:

Уравнение кривой безье по точкам Уравнение кривой безье по точкамУравнение кривой безье по точкам

Видео:Кривая Безье по трем точкам, рассчитать по формуле или нарисовать самомуСкачать

Кривая Безье по трем точкам, рассчитать по формуле или нарисовать самому

Математика

У кривых Безье есть математическая формула.

Как мы увидим далее, для пользования кривыми Безье знать её нет особенной необходимости, но для полноты картины – вот она.

Координаты кривой описываются в зависимости от параметра t⋲[0,1]

Для четырёх точек:

Вместо Pi нужно подставить координаты i-й опорной точки (xi, yi) .

Эти уравнения векторные, то есть для каждой из координат:

Вместо x1, y1, x2, y2, x3, y3 подставляются координаты трёх опорных точек, и в то время как t пробегает множество от 0 до 1 , соответствующие значения (x, y) как раз и образуют кривую.

Впрочем, это чересчур наукообразно, не очень понятно, почему кривые именно такие, и как зависят от опорных точек. С этим нам поможет разобраться другой, более наглядный алгоритм.

Видео:Делаем кривую Безье в Unity !Скачать

Делаем кривую Безье в Unity !

Рисование «де Кастельжо»

Метод де Кастельжо идентичен математическому определению кривой и наглядно показывает, как она строится.

Посмотрим его на примере трёх точек (точки можно двигать). Нажатие на кнопку «play» запустит демонстрацию.

Алгоритм построения кривой по «методу де Кастельжо»:

Рисуем опорные точки. В примере выше это 1 , 2 , 3 .

Строятся отрезки между опорными точками 1 → 2 → 3. На рисунке выше они коричневые .

Параметр t пробегает значения от 0 до 1 . В примере выше использован шаг 0.05 , т.е. в цикле 0, 0.05, 0.1, 0.15, . 0.95, 1 .

Для каждого из этих значений t :

На каждом из коричневых отрезков берётся точка, находящаяся от начала на расстоянии от 0 до t пропорционально длине. Так как коричневых отрезков – два, то и точек две штуки.

Например, при t=0 – точки будут в начале, при t=0.25 – на расстоянии в 25% от начала отрезка, при t=0.5 – 50%(на середине), при t=1 – в конце отрезков.

Эти точки соединяются. На рисунке ниже соединяющий их отрезок изображён синим .

При t=0.25При t=0.5
Уравнение кривой безье по точкамУравнение кривой безье по точкам

    На получившемся отрезке берётся точка на расстоянии, соответствующем t . То есть, для t=0.25 (первый рисунок) получаем точку в конце первой четверти отрезка, для t=0.5 (второй рисунок) – в середине отрезка. На рисунках выше эта точка отмечена красным .

    По мере того как t пробегает последовательность от 0 до 1 , каждое значение t добавляет к красной кривой точку. Совокупность таких точек для всех значений t образуют кривую Безье.

    Это был процесс для построения по трём точкам. Но то же самое происходит и с четырьмя точками.

    Демо для четырёх точек (точки можно двигать):

    • Точки по порядку соединяются отрезками: 1 → 2, 2 → 3, 3 → 4. Получается три коричневых отрезка.
    • На отрезках берутся точки, соответствующие текущему t , соединяются. Получается два зелёных отрезка .
    • На этих отрезках берутся точки, соответствующие текущему t , соединяются. Получается один синий отрезок .
    • На синем отрезке берётся точка, соответствующая текущему t . При запуске примера выше она красная .
    • Эти точки описывают кривую.

    Этот алгоритм рекурсивен. Для каждого t из интервала от 0 до 1 по этому правилу, соединяя точки на соответствующем расстоянии, из 4 отрезков делается 3, затем из 3 так же делается 2, затем из 2 отрезков – точка, описывающая кривую для данного значения t .

    Нажмите на кнопку «play» в примере выше, чтобы увидеть это в действии.

    Видео:Кривая Безье | Самый полный разбор инструмента | Принципы + навыкиСкачать

    Кривая Безье  |  Самый полный разбор инструмента  |  Принципы + навыки

    Постигая кривые Безье

    Кривые Безье — это способ определения кривой по опорным точкам.

    Для наглядности можно рассматривать их как график передвижения точки от начала до конца маршрута в зависимости от времени движения.

    Время изменяется от 0 до 1 (до 100%). То есть мы изначально знаем время, за которое нужно переместиться из начальной точки (P0) в конечную (Pn) (конкретная величина не имеет значения). На основании этого времени можно вычислить точную траекторию — по формулам.

    Берем все время за 100% (или за единицу). В момент 0 (0%) точка находится в точке P0, в момент 1 (100%) – в точке Pn. Положение точки в любой момент между этими моментами можно вычислить по формуле.

    Порядок кривой всегда на 1 меньше количества контрольных точек. Рассмотрим построение пошагово, начиная с самой простой кривой.

    Видео:Алгебраические кривые. Кривые Безье.Скачать

    Алгебраические кривые. Кривые Безье.

    Кривая Безье первого порядка

    Простейшая кривая Безье — это обычная линия. Порядок первый – значит, контрольных точек две. Ее академическое уравнение выглядит так:

    А график — вот так:

    Уравнение кривой безье по точкам

    Разберем на простейшем примере. Пусть:

    • первая контрольная точка — P0 имеет координаты (0; 0),
    • вторая (и последняя) – P1 – (5; 0).

    Сразу же проверим формулу.

    При t = 0 (в начальный момент времени) должна получиться точка P0, а при t = 1 должна получиться точка P1.

    А теперь найдем несколько точек между началом и концом. Тут используется сложение и умножение векторов, но в данном случае все интуитивно понятно:

    Все полученные точки лежат на одной прямой – это и есть кривая Безье первого порядка.

    Время идет, точка движется от старта к финишу. И в любой момент времени мы точно знаем, где она находится.

    Видео:Математика без Ху!ни. Кривые второго порядка. Эллипс.Скачать

    Математика без Ху!ни. Кривые второго порядка. Эллипс.

    Кривые Безье второго порядка и больше

    В определении кривых Безье выше первого порядка кроме начала и конца появляются дополнительные опорные точки, смысл которых сложно понять с первого захода.

    Уравнение кривой безье по точкам

    Непосредственно через них кривая не проходит, так зачем же они нужны?

    На самом деле эти точки определяют направление движения (направление изгиба кривой) и крутизну этого изгиба.

    Квадратичная кривая

    Кривая Безье второго порядка, или квадратичная, задается тремя контрольными точками:

    • P0 – начало;
    • P2 – конец;
    • P1 – вспомогательная точка, определяющая изгиб кривой.

    Маленький спойлер: кривая Безье второго порядка имеет форму параболы (не обязательно симметричной).

    Формула у нее вот такая:

    B(t) = (1 — t) 2 *P0 + 2t*(1 — t)*P1 + t 2 *P2

    Проверим, что в начале и конце движения мы окажемся в точках P0 и P2 соответственно:

    Найдем, где будет точка через половину времени t (0.5):

    B(0.5) = 0.25*P0 + 0.5*P1 + 0.25*P2 = (-0.25; 0) + (0; 1) + (0.25; 0) = (0; 1)

    То есть на половине временного интервала мы окажемся в точке (0; 1) .

    Если найти еще несколько точек, вырисуется ровная парабола. Так, в общем, и было задумано для простоты вычислений и визуальной ясности.

    Рекурсивность кривых Безье

    Волшебство кривых Безье заключается в том, что они рекурсивны. То есть умея строить кривую первого порядка, мы можем построить и квадратичную кривую, даже не зная ее формулы.

    Вернемся к предыдущему примеру:

    Предположим, что мы не знаем, как построить кривую второго порядка между P0 и P2. Но мы можем построить простейшую кривую первого порядка между P0 и P1, а также между P1 и P2, пользуясь формулой:

    Для каждого момента времени мы можем найти положение точки на каждой из этих кривых.

    Например, в момент времени 0.25 соответствующие точки Q0 и Q1 будут в таких позициях:

    Уравнение кривой безье по точкам

    Между этими точками тоже можно построить кривую первого порядка.

    Магия заключается в том, что точка на этой кривой в момент времени t = 0.25 соответствует точке на искомой кривой второго порядка в этот же момент времени.

    Распишем чуть подробнее.

    Мы хотим найти точку на кривой второго порядка P0-P11-P2 в момент времени t .

    Искомая точка – это точка на кривой Q0-Q1, соответствующая моменту времени t .

    Этот рекурсивный алгоритм построения кривой Безье носит имя Поля де Кастельжо.

    Уравнение кривой безье по точкам

    Кубическая кривая

    Кривая Безье третьего порядка, или кубическая кривая, определяется уже четырьмя опорными точками – началом, концом и двумя вспомогательными, через которые она не будет непосредственно проходить.

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

    Формула кубической кривой еще сложнее:

    B(t) = (1 — t) 3 *P0 + 3t*(1-t) 2 *P1 + 3t 2 *(1 — t)*P2 + t 3 *P3

    Вы можете попробовать эту кривую рассчитать самостоятельно.

    Обратите внимание, ее тоже можно получить рекурсивно!

    Уравнение кривой безье по точкам

    Найти точку кривой третьего порядка в момент времени t можно по следующему алгоритму:

    1. Строим кривые первого порядка P0-P1, P1-P2, P2-P3
    2. Находим на них соответствующие t точки Q0, Q1, Q2
    3. Строим кривые первого порядка Q0-Q1 и Q1-Q2
    4. Находим на них соответствующие t точки R0 и R1
    5. Строим кривую первого порядка R0-R1
    6. Находим на ней точку, соответствующую t .

    Уравнение кривой безье по точкам

    Видео:РК6. Геометрическое моделирование. Кривые Безье-БернштейнаСкачать

    РК6. Геометрическое моделирование. Кривые Безье-Бернштейна

    Зачем все это нужно?

    Круто, теперь мы умеем строить кривые Безье любого порядка, но зачем нам это нужно? Каково практическое применение этих построений?

    Кривые Безье используются в описаниях шрифтов TrueType, в SVG, GIMP и других графических форматах, в 3D-графике. Они используются даже в CSS для описания плавности анимации.

    Видео:Алгоритмы - Кривые БезьеСкачать

    Алгоритмы - Кривые Безье

    Кривые Безье и Пикассо

    Уравнение кривой безье по точкам

    Пабло Пикассо в своей студии на фоне картины «Кухня», фотография Херберта Листа.

    Видео:Кривая Безье из двух точек наглядно и простоСкачать

    Кривая Безье из двух точек наглядно и просто

    Художник и простота

    Одни из самых любимых мной работ Пабло Пикассо — это его линейные рисунки. Он изобразил на некоторых из них животных: сову, верблюда, бабочку и т.д. Эта работа под названием «Собака» висит на моей стене:

    Уравнение кривой безье по точкам

    (Можете перейти к интерактивному демо, в которой мы воссоздали «Собаку» с помощью представленных в статье математических расчётов)

    Эти рисунки чрезвычайно просты, но каким-то образом им удаётся глубоко тронуть зрителя. Они создают впечатление простоты композиции и реализации. Одно движение руки и подпись создают настоящий шедевр! Рисунок одновременно кажется и небрежной импровизацией, и точно подобранной увертюрой в симфонии изящества. На самом деле мы знаем, что процесс работы Пикассо был глубоким. Например, в 1945-1946 годах Пикассо создал серию из одиннадцати рисунков (литографий, если точнее), демонстрирующих его постепенный прогресс в визуализации быка. Первые были более-менее похожи на реалистичные, но в дальнейшем мы видим, как бык превращается в саму свою сущность, а последний рисунок состоит всего из десятка линий. В процессе развития серии рисунков мы видим быка, напоминающего некоторые из других работ Пикассо (номер 9 напоминает мне скульптуру в чикагском Daley Center Plaza). Здесь можно подробнее прочитать о серии литографий.

    Уравнение кривой безье по точкам

    «Бык» Пикассо. Фотография сделана Джереми Куном в Институте искусств в Чикаго. Нажмите на изображение, чтобы увеличить его.

    Я не буду притворяться опытным художником (я не смог бы нарисовать быка, даже если бы от этого зависела моя жизнь), зато я могу распознать математические аспекты его картин и написать чертовски хорошую программу. Есть один очевидный способ рассмотрения линейных рисунков в стиле Пикассо как математических объектов, и это конечно же кривые Безье. Давайте начнём с изучения теории кривых Безье, а потом напишем программу для их отрисовки. Используемая в ней математика не требует никаких дополнительных знаний, кроме основ алгебры и полиномов, и я постараюсь как можно меньше вдаваться в сложные подробности. Мы изучим очень простой алгоритм рисования кривых Безье, реализуем его на Javascript, а затем воссоздадим один из линейных рисунков Пикассо с помощью нескольких кривых Безье.

    Видео:CorelDRAW X5 для начинающих. «Кривая Безье» и «Перо» (3.3)Скачать

    CorelDRAW X5 для начинающих. «Кривая Безье» и «Перо» (3.3)

    Кривые Безье и параметризация

    Когда кто-нибудь просит вспомнить «кривые», большинство людей (возможно, отравленных преподаванием основ математики) или начинает трястись от страха, или рисует часть графика многочлена. Хотя это вполне правильные и уважаемые кривые, но они представляют лишь небольшую часть мира кривых. Особенно нас интересуют кривые, которые не являются частью графиков функций.

    Уравнение кривой безье по точкам

    Например, лекало — это физический шаблон, используемый для (ручного) рисования плавных кривых. Просто соединяя рёбрами любую часть этих кривых, мы обычно не можем получить график функции. Очевидно, что нам нужна более общая идея о том, что же такое кривые. Проблема в том, что в разных областях математики под «кривой» подразумеваются различные понятия. Кривые, которые мы будем изучать, называемые «кривыми Безье» — это особый случай полиномиальных плоских кривых с одним параметром. Это звучит слишком сложно, но на самом деле это означает, что всю кривую можно задать двумя многочленами: одним для значений Уравнение кривой безье по точками вторым для значений Уравнение кривой безье по точкам. Оба многочлена имеют одну переменную, которую мы назовём Уравнение кривой безье по точкам( Уравнение кривой безье по точкамопределена на множестве вещественных чисел).

    На примере всё должно стать понятнее. Давайте подберём два простых многочлена от Уравнение кривой безье по точкам, допустим, Уравнение кривой безье по точками Уравнение кривой безье по точкам. Если мы хотим найти точки на этой кривой, мы просто выбираем значения Уравнение кривой безье по точками подставляем их в оба уравнения. Например, подставив Уравнение кривой безье по точкам, мы получим точку Уравнение кривой безье по точкамна кривой. Располагая все такие значения на графике, мы получим кривую, которая точно не является графиком функции:

    Уравнение кривой безье по точкам

    Но очевидно, что мы можем записать любую функцию с одной переменной Уравнение кривой безье по точкамв таком параметрическом виде: просто выберем Уравнение кривой безье по точками Уравнение кривой безье по точкам. Итак, они на самом деле являются более общими объектами, чем обычные функции (однако в этой статье мы будем работать только с многочленами).

    Вкратце повторим: полиномиальная плоская кривая с одним параметром задаётся как пара многочленов Уравнение кривой безье по точкамот одной переменной Уравнение кривой безье по точкам. Иногда, когда нам нужно выразить всю систему одним уравнением, мы можем взять коэффициенты общих степеней Уравнение кривой безье по точками записать их как векторы Уравнение кривой безье по точками Уравнение кривой безье по точкам. Благодаря приведённому выше примеру Уравнение кривой безье по точкаммы можем переписать это как Уравнение кривой безье по точкам.

    Здесь коэффициенты — это точки на плоскости (те же, что и векторы), и мы выделяем функцию Уравнение кривой безье по точкамжирным, чтобы подчеркнуть, что выходные данные являются точкой. Изучающие линейную алгебру могут понять, что пары многочленов формируют линейное пространство, и скомбинировать их как Уравнение кривой безье по точкам. Но для нас удобнее будет воспринимать точки как коэффициенты одного многочлена.

    Мы также ограничим наше внимание рассмотрением однопараметрических плоских кривых, описываемых полиномом, для которых переменная Уравнение кривой безье по точкамдопускается на интервале от нуля до единицы. Такое ограничение может показаться странным, но на самом деле так может быть записана любая конечная однопараметрическая плоская кривая, описываемая полиномом (мы не будем вдаваться в подробности того, как это реализуется). Ради краткости далее я буду называть однопараметрическую плоскую кривую, определяемую полиномом, у которой Уравнение кривой безье по точкамнаходится в интервале от нуля до единицы, просто «кривой».

    С этими кривыми мы можем делать очень интересные вещи. Например для любых двух точек в плоскости Уравнение кривой безье по точкаммы можем описать прямую между ними как кривую: Уравнение кривой безье по точкам. И в самом деле, при Уравнение кривой безье по точкамзначение Уравнение кривой безье по точкамточно равно Уравнение кривой безье по точкам, при Уравнение кривой безье по точкамточно равно Уравнение кривой безье по точкам, и уравнение является линейным полиномом при Уравнение кривой безье по точкам. Более того (если не вдаваться в подробности матанализа), линия Уравнение кривой безье по точкампроходит с «единичной скоростью» от Уравнение кривой безье по точкамдо Уравнение кривой безье по точкам. Другими словами, мы можем воспринимать Уравнение кривой безье по точкамкак описывающую движение частицы из Уравнение кривой безье по точкампо времени, и во время Уравнение кривой безье по точкамчастица пройдёт путь на четверть, а во время Уравнение кривой безье по точкампройдёт половину пути, и т.д. (Примером прямой, не имеющей единичную скорость, является, например Уравнение кривой безье по точкам.)

    Для более общего случая давайте добавим третью точку Уравнение кривой безье по точкам. Мы можем описать путь, проходящий через Уравнение кривой безье по точкамв Уравнение кривой безье по точкам, и он «направляется» точкой Уравнение кривой безье по точкам, лежащей посередине. Эта идея «направляющей» точки немного абстрактна, но в отношении вычислений не более сложна. Вместо движения из одной точки в другую с постоянной скоростью, мы хотим двигаться из одной линии к другой с постоянной скоростью. То есть мы можем назвать две кривые, описывающие прямые из Уравнение кривой безье по точками Уравнение кривой безье по точкамкривыми Уравнение кривой безье по точками Уравнение кривой безье по точкам. Тогда кривая, «направляемая» точкой Уравнение кривой безье по точкам, может быть записана как кривая

    Уравнение кривой безье по точкам

    Выполнив все эти умножения, мы получим формулу

    Уравнение кривой безье по точкам

    С течением времени точка Уравнение кривой безье по точкамдвижется вдоль прямой между точками Уравнение кривой безье по точками Уравнение кривой безье по точкам, которые также движутся. Так мы получаем кривую, которая выглядит следующим образом

    Уравнение кривой безье по точкам

    Этот скриншот взят из потрясающего демо консультанта по визуализации данных Джейсона Дейвиса. Он идеально демонстрирует математическую идею. В демо можно перетаскивать все три точки, чтобы посмотреть, как это влияет на конечную кривую. Стоит поиграть с ней хотя бы пять минут.

    Вся идея кривых Безье заключается в обобщении этого принципа: имея список точек Уравнение кривой безье по точкамна плоскости, мы хотим описать кривую, которая проходит от первой до последней точки, и «направляется» между остальными точками. Кривая Безье является реализацией такой кривой (однопараметрической плоской кривой, определяемой полиномом), которая становится индуктивным продолжением описанного выше: мы движемся с единичной скоростью из кривой Безье, заданной первыми Уравнение кривой безье по точкамточками списка до кривой, заданной последними Уравнение кривой безье по точкамточками. В простейшем случае это отрезок прямой линии (или единственная точка, если угодно). С формальной точки зрения,

    Определение: для заданного множества точек на плоскости Уравнение кривой безье по точкаммы рекурсивно определяем кривую Безье степени Уравнение кривой безье по точкамкак

    Уравнение кривой безье по точкам

    Мы назовём Уравнение кривой безье по точкамконтрольными точками Уравнение кривой безье по точкам.

    Хотя концепция перемещения с единичной скоростью между двумя кривыми Безье более низкого порядка является настоящей сутью дела (и позволяет нам подойти с к решению с вычислительной точки зрения), можно просто всё это перемножить (с помощью формулы биномиальных коэффициентов) и получить формулу в явном виде. Она будет следующей:

    Уравнение кривой безье по точкам

    Например, кубическая кривая Безье с контрольными точками Уравнение кривой безье по точкамбудет иметь уравнение

    Уравнение кривой безье по точкам

    Кривые Безье более высокого порядка может быть достаточно сложно отобразить геометрически. Например, ниже показана кривая Безье пятой степени (с шестью контрольными точками).

    Уравнение кривой безье по точкам

    Кривая Безье пятой степени, иллюстрация из Википедии.

    Отрисованные дополнительные отрезки прямых демонстрируют рекурсивную природу кривой. Самые простые — зелёные точки, перемещающиеся между контрольными точками. Синие точки перемещаются по отрезкам прямых между зелёными точками, розовые перемещаются по отрезкам между синими, оранжевые — между розовыми, и, наконец, красная точка перемещается по отрезку прямой между оранжевыми точками.

    Без рекурсивной структуры задачи (просто из наблюдения за кривой) было бы сложно понять, как можно всё это вычислить. Но как мы увидим, алгоритм отрисовки кривой Безье очень естественен.

    Видео:Лекция 6 | Компьютерная графика | Виталий Галинский | ЛекториумСкачать

    Лекция 6 | Компьютерная графика | Виталий Галинский  | Лекториум

    Кривые Безье как данные и алгоритм де Кастельжо

    Давайте выведем и реализуем алгоритм отрисовки кривой Безье на экране, воспользовавшись исключительно возможностью рисования прямых линий. Для простоты мы ограничимся рассмотрением только кривых Безье третьей степени (кубических). И в самом деле, любая кривая Безье по рекурсивному определению может быть записана как сочетание кубических кривых, и на практике кубические кривые обеспечивают баланс между эффективностью вычислений и выразительностью. Весь код в этом посте написан на Javascript и выложен на странице этого блога на Github.

    Итак, кубическая кривая Безье представляется в программе списком из четырёх точек. Например,

    В большинстве графических библиотек (в том числе в стандартной HTML5 canvas) существует графический примитив, способный выводить кривые Безье на основании списка из четырёх точек. Но предположим, что у нас нет такой функции. Предположим, что мы можем рисовать только прямые линии. Как же мы можем нарисовать аппроксимацию кривой Безье? Если такой алгоритм существует (а он есть, и мы убедимся в этом), то мы можем создать настолько точную аппроксимацию, что она будет визуально неотличима от истинной кривой Безье.

    Важнейшее свойство кривых Безье, которое позволит нам создать такой алгоритм, заключается в следующем:

    Любую кубическую кривую Безье Уравнение кривой безье по точкамот начала до конца можно разделить на две, которые вместе будут описывать ту же кривую, что и Уравнение кривой безье по точкам.

    Давайте посмотрим, как же это сделать. Пусть Уравнение кривой безье по точкамбудет кубической кривой Безье с контрольными точками Уравнение кривой безье по точкам, и допустим, что мы хотим разделить её ровно пополам. Мы заметим, что формула кривой при подстановке Уравнение кривой безье по точкампримет вид

    Уравнение кривой безье по точкам

    Более того, наше рекурсивное определение даёт нам способ вычислить точку на основании кривых меньшей степени. Но когда вычисления выполняются при 1/2, их формулы достаточно просто записать. Изображение выглядит так:

    Уравнение кривой безье по точкам

    Зелёные точки — это кривые первой степени, розовые точки — кривые второй степени, а синяя точка — это кубическая кривая. Мы заметим, что поскольку каждая из кривых вычисляется при Уравнение кривой безье по точкам, каждую из этих точек можно описать как среднюю точку уже известных нам точек. Поэтому Уравнение кривой безье по точкам, и т.д.

    На самом деле, разделение на две нужные нам кривые точно задаётся этими точками. То есть половина кривой задаётся Уравнение кривой безье по точкамс контрольными точками Уравнение кривой безье по точкам, в то время как «правая» половина Уравнение кривой безье по точкамимеет контрольные точки Уравнение кривой безье по точкам.

    Как мы можем быть уверены, что это точно те же кривые Безье? Ну, это просто полиномы. Мы можем проверить их на равенство с помощью запутанных алгебраических вычислений. Но стоит заметить, что поскольку Уравнение кривой безье по точкампроходит только полпути вдоль Уравнение кривой безье по точкам, то проверка их на равенство аналогична приравниванию Уравнение кривой безье по точкамс Уравнение кривой безье по точкам, поскольку Уравнение кривой безье по точкамизменяется в интервале от нуля до единицы, Уравнение кривой безье по точкамизменяется в интервале от нуля до половины. Аналогично, мы можем сравнить Уравнение кривой безье по точкамс Уравнение кривой безье по точкам.

    Алгебраические вычисления очень запутаны, но вполне посильны. В доказательство привожу скринкаст того, как я выполняю вычисления, доказывающие идентичность двух кривых.

    Теперь, когда мы всё проверили, у нас есть хороший алгоритм для разделения кубической кривой Безье (или любой кривой Безье) на две части. На Javascript он будет выглядеть так:

    Здесь curve — это список из четырёх точек, как описано в начале этого раздела, а выходными данными является список двух кривых с правильными контрольными точками. Используемая функция midpoints достаточно проста, и для полноты мы тоже добавим её сюда:

    Она просто получает на входе список точек и вычисляет их последовательные средние точки. То есть список из Уравнение кривой безье по точкамточек превращается в список из Уравнение кривой безье по точкамточек. Как мы видели, нам нужно вызывать эту функцию Уравнение кривой безье по точкамдля вычисления сегментации кривой Безье степени Уравнение кривой безье по точкам.

    Как я объяснил ранее, мы можем продолжать подразделять нашу кривую снова и снова, пока каждая из небольших частей не станет практически прямой. То есть наша функция для отрисовки кривой Безье будет следующей:

    Если выразить словами, то поскольку наша кривая не «плоская», мы хотим рекурсивно подразделять и отрисовывать каждую часть. Если она плоская, то мы можем просто отрисовать три отрезка прямых кривой и логично считать, что это будет хорошей аппроксимацией. Используемая здесь переменная контекста представляет собой холст (canvas), на которой должна выполняться отрисовка; её нужно передавать фунции drawSegments , которая просто отрисовывает на холсте прямую линию.

    Разумеется, это ставит перед нами очевидный вопрос: как мы можем определить, что кривая Безье плоская? Для этого есть множество способов. Можно вычислять углы отклонения (от прямой) в каждой внутренней контрольной точке и складывать их. Или можно вычислить объём образуемого четырёхугольника. Однако вычисление углов и объёмов обычно не так удобно: на расчёты углов тратится много времени, объёмы имеют проблемы со стабильностью, а стабильные алгоритмы не очень просты. Нам нужно измерение, для которого достаточно простой арифметики и, возможно, проверки нескольких логических условий.

    Оказывается, что такое измерение существует. Его изначально приписывают Роджеру Уилкоксу, но оно достаточно просто выводится вручную.

    В сущности, мы хотим измерить «плоскостность» кубической кривой Безье вычислением расстояния от настоящей кривой во время Уравнение кривой безье по точкамдо того места, где кривая должна бы быть во время Уравнение кривой безье по точкам, если она является прямой.

    Формально, имея заданную Уравнение кривой безье по точкамс контрольными точками Уравнение кривой безье по точкам, мы можем определить прямолинейную кубическую кривую Безье как колоссальную сумму

    Уравнение кривой безье по точкам

    Здесь не происходит ничего волшебного. Мы просто задаём кривую Безье с контрольными точками Уравнение кривой безье по точкам. Нужно воспринимать их как точки, которые находятся на 0, 1/3, 2/3 и 1 доли пути от Уравнение кривой безье по точкамдо Уравнение кривой безье по точкамна прямой линии.

    Теперь мы зададим функцию Уравнение кривой безье по точкам, которая будет расстоянием между двумя кривыми в одно и то же время Уравнение кривой безье по точкам. Значение плоскостности Уравнение кривой безье по точкам— это максимум функции Уравнение кривой безье по точкампо всем значениям Уравнение кривой безье по точкам. Если значение плоскостности ниже определённого уровня допуска, то мы будем считать кривую плоской.

    Добавив немного алгебры, мы можем упростить это выражение. Во-первых, значение Уравнение кривой безье по точкам, для которого расстояние максимально, аналогично тому, у которого максимален квадрат, поэтому мы можем избежать вычисления квадратного корня в конце и учитывать это при выборе допуска плоскостности.

    Теперь давайте запишем разность как один полином. Во-первых, мы можем избавиться от троек в Уравнение кривой безье по точками записать полином как

    Уравнение кривой безье по точкам

    и поэтому Уравнение кривой безье по точкамравно (при сложении коэффициентов подобных членов Уравнение кривой безье по точкам

    Уравнение кривой безье по точкам

    Вынеся за скобки Уравнение кривой безье по точкамиз обоих членов и обозначив Уравнение кривой безье по точкам, Уравнение кривой безье по точкам, получим

    Уравнение кривой безье по точкам

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

    Применив элементарные вычисления с единственной переменной, получим, что максимальное значение Уравнение кривой безье по точкамдля Уравнение кривой безье по точкамоказывается равным Уравнение кривой безье по точкам. А норма вектора — это просто сумма квадратов его компонентов. Если Уравнение кривой безье по точками Уравнение кривой безье по точкам, то представленная выше норма равна

    Уравнение кривой безье по точкам

    И заметьте: для любых вещественных чисел Уравнение кривой безье по точкамвеличина Уравнение кривой безье по точкамв точности является прямой линией из Уравнение кривой безье по точкамв Уравнение кривой безье по точкам, которая нам хорошо знакома. Максимум для всех Уравнение кривой безье по точкамот нуля до единицы очевидно будет равен максимуму конечных точек Уравнение кривой безье по точкам. Так что максимум нашей функции расстояния Уравнение кривой безье по точкамограничен

    Уравнение кривой безье по точкам

    И поэтому наше условие плоскостности заключается в том, чтобы это ограничение было меньше некоторого допуска. Мы можем безопасно разложить 1/16 на множители в это ограничение допуска, и этого будет достаточно для того, чтобы записать функцию.

    Вот и она. Мы написали простую HTML-страницу, чтобы получить доступ к элементу canvas и несколько вспомогательных функций для отрисовки отрезков прямой, когда кривая достаточно плоская, и представили конечный результат в этом интерактивном демо (контрольные точки можно двигать).

    Изображение, которое вы видиет на этой странице (ниже) — это моя визуализация «Собаки» Пикассо, нарисованная как последовательность кривых Безье. Думаю, что сходство вполне убедительное.

    «Собака» Пикассо, собранная из последовательности девяти кривых Безье.

    Хотя сам рисунок изобрели не мы (и потому не можем поставить под ним свою подпись), мы смогли представить его как последовательность кривых Безье. Можно только назвать их художественной работой. Здесь мы свели представление к одному файлу: первая строка — это размер холста, а каждая последующая строка представляет кубическую кривую Безье. Комментарии добавлены для лучшей читаемости.

    Уравнение кривой безье по точкам

    «Собака», Джереми Кун, 2013 год.

    Стандартизация кажется мне важной, поэтому мы определим новый тип файла «.bezier», который будет иметь показанный выше формат:

    Здесь первые два целых числа определяют размер холста, первое (необязательное) целое число в каждой строке задаёт ширину линии, а curve имеет вид

    Если int в начале строки отсутствует, то линии задаётся ширина в три пикселя.

    В целом, файл .bezier может задавать кривую с произвольным количеством контрольных точек, однако представленный выше код не отрисовывает их в общем виде. В качестве упражнения попробуйте написать программу, которая получает на входе файл .bezier, а на выходе создаёт изображение рисунка. Для этого потребуется расширить представленный выше алгоритм, чтобы он мог рисовать произвольные кривые Безье, циклически производя вычисления средних точек и отслеживая те из них, которые оказываются конечным подразделением. Или же можно написать программу, получающую на входе файл .bezier только с кубическими кривыми Безье, а на выходе выдающую файл SVG рисунка (SVG поддерживает только кубические кривые Безье). То есть файл .bezier является упрощением (меньше возможностей) и расширением (кривые Безье произвольной степени) файла SVG.

    Мы не так сильно углублялись в теорию кривых Безье, как могли бы. Если вы хотите изучить тему глубже (и с использованием матанализа), то см. этот длинный вводный курс. В нём содержится практически всё, что нужно знать о кривых Безье, а также представлены написанные на Processing интерактивные демо.

    Видео:Математика без Ху!ни. Уравнение плоскости.Скачать

    Математика без Ху!ни. Уравнение плоскости.

    Искусство низкой сложности

    У того, что мы сделали с «Собакой» Пикассо, есть некое философское значение. Ранее в этом блоге мы исследовали идею искусства низкой сложности, и здесь она полностью применима. Основная мысль заключается в том, что «красивое» искусство имеет описание малой длины; если более формально, то «сложность» объекта (представленного в тексте) — это длина самой короткой программы, дающей на выходе этот объект при отсутствии входных данных. Подробнее об этом можно прочитать в нашем введении в колмогоровскую сложность. Тот факт, что мы можем описать линейные рисунки Пикассо малым числом кривых Безье (и относительно короткой программой, дающей на выходе кривые Безье), должен быть глубоким заявлением о красоте самого искусства. Очевидно, что такой взгляд очень субъективен, но у него есть свои сторонники.

    Сегодня существует интерес к генерируемому компьютером искусству. Например, в этих недавних соревнованиях по программированию (статья на нидерландском) участникам дали задание сгенерировать рисунок, напоминающий работу Пита Мондриана. Идея заключалась в том, что чем элегантнее алгоритм, тем выше будет его оценка. Для генерации работ Мондриана победитель использовал хэши MD5, и есть ещё множество других впечатляющих примеров (по ссылке выше представлена галерея готовых работ).

    В предыдущем посте об искусстве низкой сложности мы исследовали возможность представления всех изображений в системе координат, в которой используются окружности с закрашенным внутренним пространством. Но очевидно, что в такой системе координат нельзя представить «Собаку» с очень низкой сложностью. Похоже, что кривые Безье — это гораздо более естественные системы координат. Небольшие усовершенствования, включающие в себя длину линий и небольшие искажения, не влияют на конечную сложность. Кубическую кривую Безье можно описать любым множество из четырёх точек, а для более «запутанных» описаний (с повышенной сложностью) требуется большее количество точек. Кривые Безье можно произвольно масштабировать, и это не изменит значительно сложность кривой (несмотря на то, что масштабирование на многие порядки величины добавит увеличение сложности с логарифмическим множителем, оно довольно мало). Кривые с большой шириной линий немного сложнее, чем с малой шириной, а для представления множества мелких острых изгибов требуется больше кривых, чем для длинных и плавных дуг.

    Недостатком является сложность представления в виде кривой Безье окружности. На самом деле, точно это сделать невозможно. Несмотря на простоту этого объекта (он даже задаётся как единственный многочлен, хотя и с двумя переменными), лучшее, что можно с ним сделать — аппроксимировать его. То же относится и к эллипсам. На самом деле есть способы обхода этой проблемы (концепция рациональных кривых Безье, которые являются частными многочленов), но они добавляют в алгоритм отрисовки неотъемлемую сложность, а аппроксимации с использованием обычных кривых Безье выглядят достаточно хорошо.

    Итак, мы определим сложность рисунка как количество битов в виде файла .bezier (комментарии при вычислениях не учитываются).

    Настоящей наградой, которую мы ещё исследуем, будет нахождение способа автоматической генерации искусства. То есть реализации одной из двух возможностей:

    1. Задав что-то вроде случайного начального числа (seed), написать программу, создающую псевдослучайный линейный рисунок.
    2. Задав рисунок, создать изображение .bezier, точно воспроизводящее рисунок как линейный рисунок.

    Мы попробуем исследовать эти возможности в последующем посте. Для этого могут потребоваться какие-нибудь алгоритмы локального поиска, генетические алгоритмы или другие способы.

    🔍 Видео

    1. Blender. Curve Pen (Инструмент Перо) | КриваяСкачать

    1. Blender. Curve Pen (Инструмент Перо) | Кривая

    Blender Объекты По Кривой | Blender Массив По Кривой | Blender CurveСкачать

    Blender Объекты По Кривой | Blender Массив По Кривой | Blender Curve

    Интерактивная геометрия на примере кривых БезьеСкачать

    Интерактивная геометрия на примере кривых Безье

    Урок 10 . Движение объектов. Кривая Безье.Скачать

    Урок 10 . Движение объектов. Кривая Безье.

    2 Кривые БезьеСкачать

    2  Кривые Безье

    Как работают кривые Безье | Иван Гладких | ProsmotrСкачать

    Как работают кривые Безье | Иван Гладких | Prosmotr

    Кривая БезьеСкачать

    Кривая Безье

    Corel draw как рисовать кривой безьеСкачать

    Corel draw как рисовать кривой безье
Поделиться или сохранить к себе: