Демо

17.06.2008 от iv

Обновилась демка: http://bezier.ru/wp-content/uploads/2010/03/BezierTest.swf?demo=1
Надеюсь, она стала нагляднее и удобнее.

Рубрики: Новости | Комментарии (2) »

Обзор возможностей класса Bezier

04.06.2008 от iv

Конструктор

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

Параметры конструктора — три точки на плоскости, объекты класса Point, а так же четвертый параметр — булева переменная, указывающая на режим работы с кривой.

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

В целях обеспечения возможности изменения работы конструктора в подклассах, вся логика конструктора вынесена в protected метод initInstance(…).

Здесь же следует упомянуть метод clone, создающий копию текущей кривой. Других способов создания нового экземпляра класса не предусмотрено.

В предыдущей AS2 версии класса были предусмотрены методы создания экземпляра класса Bezier из строки, массива и XML. Однако, эта функциональность не была включена в текущую версию, поскольку не соответствует назначению пакета, а также может быть легко реализована самостоятельно в классе-фабрике.

Основные свойства

Контрольные точки, определяющие саму кривую Безье, и являются основными свойствами класса — start, control, end. Реализованы они как get/set свойства в целях возможности переопределения этих свойств в подклассах. Я рассуждал так: при замене контрольной точки на другую может потребоваться дополнительная функциональность, например перерисовка кривой. Эту логику проще всего реализовать переопределив свойства в подклассе.

Еще одним важным свойством является то, как мы относимся к кривой: как к сегменту, ограниченному начальной и конечной точками или как к бесконечной кривой. Значение этого свойства влияет на результаты вычисления пересечений, а также при вычислении точки на кривой, ближай$$$$$ей к произвольно заданной на плоскости.

Геометрические свойства

Длина сегмента кривой Безье, ограниченного начальной и конечной точками может быть получена из свойства length. Для получения длины произвольного сегмента кривой используется метод getSegmentLength(…), принимающий в качестве параметра time-итератор точки на кривой, до которой требуется найти длину сегмента от начальной точки. В случае, если потребуется найти длину сегмента, не начинающегося с начальной точки, то достаточно получить значения длины от начала кривой до начальной и конечной точки сегмента и вычислить разницу.

Площадь фигуры, образуемой кривой Безье и ее основанием, можно получить используя свойство area. Площадь этой фигуры равна 2/3 площади описывающего треугольника. Для вычисления площади сложной фигуры, отрисованной отрезками и кривыми Безье второго порядка, в общем случае следует:

  • разбить фигуру на треугольники, используя описывающие треугольники там, где контур образован кривыми;
  • суммировать их площадь;
  • вычесть все значения area для случаев вогнутых кривых, и вычесть половину значения area для случаев выпуклых кривых.

В случае выпуклых кривых вычитается половина area по той причине, что остав$$$$$аяся часть — фигура, образованная кривой и сторонами описывающего треугольника имеет площадь, равную 1/3 описывающего треугольника, или половине area.

Геометрический центр тяжести описывающего треугольника вычисляется как среднее арифметическое его вер$$$$$ин.

Описывающий треугольник делится кривой Безье на две части: вне$$$$$нюю и внутреннюю фигуры. Внутренняя фигура образуется кривой Безье и линией SE. Вне$$$$$няя фигура образуется кривой Безье и сторонами описывающего треугольника SC и CE.

Центры тяжести описывающего треугольника и фигур Безье находятся на одной линии, линии соединяющей середину основания (M) и управляющую точку C.

Центр тяжести внутренней фигуры находится на расстоянии 0.2 от основания до управляющей точки, описывающего треугольника — 1/3, и вне$$$$$ней фигуры на 0.6.

Для получения центров тяжести используйте свойства класса triangleCentroid, internalCentroid, externalCentroid. На демонстрации эти точки обозначены как Gt, Gi, Ge.

Габаритный прямоугольник можно получить используя свойство bounds. Следует заметить, что расчеты производятся для сегмента, ограниченного точками start и end, вне зависимости от текущего значения свойства isSegment, поскольку неограниченная кривая Безье бесконечна и о ее габаритах рассуждать бессмысленно.

Если требуется получить габаритный прямоугольник какой-либо части текущей кривой Безье, то вначале следует получить методом getSegment(…) новый объект Bezier и, в свою очередь, у него получать габаритный прямоугольник.

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

Родительская парабола

Как я уже писал в предыдущих статьях, кривая Безье второго порядка, будучи построенной с time-итератором от минус бесконечности до плюс бесконечности, является параболой. Соответственно, сегмент кривой Безье, ограниченный точками start и end является сегментом параболы. Причем, зная контрольные точки Безье можно вычислить родительскую параболу, что и реализуют свойства parabolaVertex и parabolaFocusPoint.

Зная вер$$$$$ину параболы и фокус несложно вычислить все остальные параметры параболы и сделать необходимые расчеты, если они не реализованы классом Bezier.

Тут следует заметить, что класс Bezier служит исключительно для ре$$$$$ения наиболее часто встречающихся геометрических задач.

В процессе реализации класса авторами была проведена боль$$$$$ая работа и в финале функциональность класса при$$$$$лось существенно сокращать, оставив только самое необходимое. Некоторые из геометрических задач перекочевали из класса в примеры использования.

Мы надеемся, что практика использования на$$$$$его пакета классов поставит новые, еще не ре$$$$$енные задачи, и вы нам о них сообщите. Мы с удовольствием возьмемся за их ре$$$$$ение.

Точки на кривой

Получение точки по time-итератору производится методом getPoint(…). Этот метод преобразует точку на кривой, заданную time-итератором в точку на плоскости.

При вычислениях точки на кривой, методы класса возвращают time-итератор. По-сути, используется одномерное представление точки, что позволяет в промежуточных вычислениях избежать постоянных преобразований точки из двумерной в одномерную и наоборот.

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

Получение ближай$$$$$ей точки на кривой до произвольно заданной производится методом getClosest(…) и часто используется как операция, обратная получению точки по time-итератору.

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

На демонстрации в примерах 2 и 3 показаны особенности метода и способы его применения.

Получение точки по дистанции по кривой производится методом getTimeByDistance(…). Последовательность точек, находящихся на одинаковом расстоянии друг от друга луч$$$$$е получать методом getTimesSequence(…).

Эти методы — одна из самых сложных и отличительных составляющих на$$$$$его класса Bezier. Хотя мы и не на$$$$$ли чисто математического ре$$$$$ения этих задач, однако применение метода Ньютона позволило добиться высокой производительности вычислений.

Применение этих методов самое $$$$$ирокое – от рисования кривых пунктиром до вычисления позиции объекта, движущегося по траектории заданной кривыми.

В примерах, прилагающихся к пакету, рассмотрены варианты применения.

$$$$$зменение кривой

Провести кривую через заданную точку требуется, например, при организации визуального редактирования кривой с помощью мы$$$$$и, когда пользователь хватает мы$$$$$ью за произвольный участок кривой и, перемещая мы$$$$$ь, изменяет ее. Эту функциональность реализует метод setPoint(…).

Переместить и повернуть кривую можно используя методы offset(…) и angleOffset(…) соответственно. Думаю, особых пояснений тут не требуется.

Сегмент кривой

Сегмент кривой Безье второго порядка также является кривой Безье второго порядка и его можно получить методом getSegment(…). Сегмент можно получить в любых пределах time-итераторов.

Пересечения

В классе реализовано вычисление пересечений кривой Безье второго порядка с другой кривой Безье второго порядка, а также с линией. Результатом пересечения всегда является объект класса Intersection, описывающий пересечения. Если пересечения нет, возвращается null.

В данный момент еще не окончательно реализована проверка соответствия пересечения значению свойства isSegment. TODO, что я еще могу сказать.

$$$$$ван Дембицкий

Рубрики: Примеры использования классо, начинающим | Комментарии (8) »

Реализация пакета Bezier

08.03.2008 от iv

Введение

Для программного рисования во Flash используется два метода: lineTo() и curveTo(), реализующие соответственно отрисовку отрезка и кривой Безье второго порядка.
В редакторе Flash имеется возможность отрисовывать кривые с помощью кривых Безье третьего порядка, однако, на этапе компиляции, они аппроксимируются кривыми Безье второго порядка.
В итоге, все векторные фигуры в скомпилированном swf файле реализованы с помощью отрезков или кривых Безье второго порядка.
В результате возникает целый спектр задач, для ре?ения которых требуется математический аппарат работы с отрезками и кривыми Безье второго порядка.

Базовые задачи класса

1. управление:

  • с помощью контрольных точек;
  • установка заданной точки в произвольно заданные координаты;
  • поворот относительно произвольно заданной точки;
  • смещение на заданное расстояние.

2. геометрические свойства:

  • получение точки на плоскости по известному time-итератору;
  • родители (прямая для отрезка и парабола для кривой Безье)
  • длина заданного сегмента
  • габаритный прямоугольник
  • площадь (для кривой Безье)
  • касательные

3. получение точек на кривой:

  • по дистанции от начала;
  • ближай?ей до произвольно заданной;
  • пересечения с другими кривыми и отрезками.

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

Собственно, перечисленные базовые задачи и реализованы в этом пакете классов.
Примеры ре?ения других практических задач вынесены в пакет howtodo.

Концепции

1. Классы Bezier и Line реализованы схожим образом и подавляющее боль?инство их методов имеют либо схожий, либо аналогичный синтаксис, определенный интерфейсом IParametric.
Разумеется, есть и отличия: к примеру, у Line не может быть свойства area, и отсутствует управляющая точка control; у Bezier, в свою очередь нет свойства angle, присутствующего в Line.

2. Геометрические фигуры(линии), реализованные в классах Line и Bezier, задаются в параметрической форме, и каждая точка фигуры характеризуется time-итератором.
Возможно, что поначалу покажется неудобным, что при вычислении точки на кривой возвращается не привычный всем объект класса Point, а time-итератор, являющийся Number. Однако такая реализация позволяет избежать избыточных конвертаций при последующих расчетах.

Универсально точной характеристикой положения точки на фигуре является time-итератор. Конвертировать в объект Point точку заданную time-итератором можно используя метод getPoint().
Обратное действие предполагает, что точка не обязательно математически точно должна принадлежать линии или кривой. Поэтому, при необходимости получения ее time-итератора, используйте метод getClosest().

3. Объекты Bezier и Line могут быть бесконечны, либо ограничены конечными точками start и end.
Ограниченность может быть установлена свойством isSegment (по умолчанию true).
Если задать isSegment=false, то возвращаемые методами значения будут содержать точки, в том числе, лежащие за пределами сегмента start-end. В противном случае, возвращаемые методами значения будут содержать только точки, принадлежащие сегменту лежащему между start и end.

Класс Bezier представляет кривую Безье второго порядка в параметрическом представлении, задаваемую точками на плоскости start, control и end и реализован в поддержку встроенного метода curveTo().
В классе реализованы свойства и методы, предоставляющие доступ к основным геометрическим свойствам этой кривой.

Краткие сведения о кривой Безье второго порядка

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

Pt = S*(1-t)2 + 2*C*(1-t)*t + E*t2

где:

  • t (time) — time-итератор точки;
  • S (start) — начальная опорная (узловая) точка (t=0) (anchor point);
  • С (control) — управляющая точка (direction point);
  • E (end) — конечная опорная (узловая) точка (t=1) (anchor point).

Построение производится итерационным вычислением множества точек кривой, с изменением значения итератора t в пределах от нуля до единицы.

Точка кривой Безье характеризуется time-итератором.
Две точки кривой, имеющие одинаковый time-итератор совпадут.
В общем случае две точки кривой Безье второго порядка с различным time-итератором не совпадут.

Свойства кривой Безье второго порядка

  • кривая непрерывна;
  • кривая остается кривой Безье при любых афинных преобразованиях: вращение, мас?табирование, переенос;
  • все точки кривой Безье лежат в пределах треугольника ?SCE;
  • точки S и E всегда принадлежат кривой Безье и ограничивают ее;
  • точки с равномерно изменяющимся итератором распределены плотнее на участках с б?ль?им изгибом;
  • вер?ина кривой Безье — точка с итератором t=0.5 лежит на середине отрезка, соединяющем С и середину отрезка SE;
  • точка C в общем случае не принадлежит кривой и лежит на пересечении касательных к кривой в точках S и E;
  • если точка С лежит на прямой SE, то такая кривая является вырожденной;
  • площадь фигуры, образуемой кривой Безье и отрезком SE равняется 2/3 площади описывающего треугольника. Центр тяжести этой фигуры находится на расстоянии 1/5 от середины основания SE до управляющей точки C;

Кривая Безье и парабола

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

Это свойство также относится и к кривым Безье других степеней. Так, к примеру, отрезок можно рассматривать как Безье первого порядка, а его родителем будет линия, которой принадлежит этот отрезок.
Класс Line именно так интерпретирует отрезок для упрощения использования совместно с классом Bezier.
Кривая Безье третьего порядка на плоскости – сегмент проекции на плоскость кубической параболы, построенной в трехмерном пространстве.
? общий случай: Кривая Безье порядка N на плоскости – сегмент проекции на плоскость N-мерной кривой, построенной в N-мерном пространстве.

?менования и условные обозначения

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

  • треугольник Безье, описывающий треугольник — треугольник, образованный контрольными точками SCE;
  • основание, основание кривой Безье — отрезок, образованный контрольными точками SE, основание треугольника SCE;
  • ось, ось кривой, осевая линия — линия, проходящая через середину основания, вер?ину и управляющую точку C
  • итератор, time-итератор, time, t — числовое значение, характеризующее положение точки на кривой Безье.
  • родительская парабола, родительская кривая – парабола, которой принадлежит данная кривая Безье (по умолчанию считаем, что кривая Безье ограничена в рамках значений итератора от 0 до 1).

Точки лежащие на кривой

BezierPoints

  • S (Start) — начальная опорная (узловая) точка (t=0) (anchor point)
  • С (Control) — управляющая (направляющая) точка (direction point)
  • E (End) — конечная опорная (узловая) точка (t=1) (anchor point)
  • V (Vertex) — вер?ина кривой (t=0.5)
  • Pt (Point, time) — точка на кривой, заданная итератором t
  • T (Top) — вер?ина родительской параболы

Другие точки

  • M (Middle) — середина основания — отрезка SE
  • St (Start, time) — точка на отрезке SC, заданная итератором t
  • Et (End, time) — точка на отрезке CE, заданная итератором t
  • F (Focus) — фокус родительской параболы.
  • D (Directrix) — точка пересечения оси родительской параболы и директрисы родительской параболы.
  • Gi (center of Gravity, internal) — центр тяжести фигуры образуемой кривой Безье и основанием описывающего треугольника SE.
  • Ge (center of Gravity, external) — центр тяжести фигуры образуемой кривой Безье и сторонами описывающего треугольника SC и CE.
  • Gt (center of Gravity, triangle) — центр тяжести описывающего треугольника SCE.

?ван Дембицкий

Сергеев: даже «камасутра» начинается с главы «введение»…

Рубрики: Примеры использования классо, начинающим | Комментарии (6) »

Как работать с пакетом классов Bezier

07.03.2008 от iv

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

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

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

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

Мы разместили пакет классов на сервисе GoogleCode, что возможно поставило тебя в тупик. Как этим пользоваться?

Если ты программируе?ь непосредственно во Flash IDE, то достоен почетного знака «Заслуженный мазохист России». Всё это потому, что тебе приходится делать два разных дела одновременно: думать когда программируе?ь. Но ты пропустил новость: уже есть среда разработки, которая позволяет не думать, а тупо программировать.
Есть, конечно среда, в которой совсем программировать не нужно, но она обходится куда дороже чем FDT.

- А вот так, чтобы не накладно и, при этом минимизировать «программировать«, тем самым максимизируя «тупо«, да еще без потери качества? – спроси?ь ты.
- Да, возможно, но для этого придется установить целый комплект: Eclipse + FDT, Subclipse и научиться использовать публичные библиотеки классов.

Поскольку инструкций по установке этих ?тук написано тонны, считаем, что у тебя всё получилось нарядно, и в своем повествовании я плавно перехожу к главному: а как всё же стащить пакет классов Bezier себе на комп.

В FDT открывай File – New – Other, в открыв?емся окне кликай SVN и там выбери Check out projects from SVN и жми Next. Создай New repository location указав http://bezier.googlecode.com/svn/trunk/ После этого начнется спло?ной пендинг. Дождись когда отпендится и выбери папочку bezier. После этого можно со всем согла?аться, учитывая, что у нас проект AS3.

? вот, настал волнующий момент: у тебя в FDT есть проект, именуемый bezier. Поздравляю! Самое главное постараться не испортить этот триумф вопросом:
- А нахрена мне ва? bezier нужен?
Потому что об этом я расскажу только в следующий раз.

?ван Дембицкий

Сергеев: Л.Н. Толстой. «Война и Мир», 2 том. Про третий том я расскажу только в следующий раз.

Рубрики: начинающим | Комментарии (5) »

Текст вдоль кривой Безье

06.03.2008 от Sergeyev

1

исходники

Александр Сергеев

Дембицкий: в первом классе злая-презлая учительница учила Са�?у Сергеева писать ровно по тетрадным линеечкам. Он до сих пор мстит.

Рубрики: Примеры использования классо | Комментарии (9) »

Привет, мир!

06.03.2008 от Sergeyev

Теперь сайт bezier.ru выглядит так. Мы ре?или перейти в формат блога, надеясь что это простимулирует нас боль?е работать над проектом, и легче рассказывать вам о возможностях пакета классов Bezier. На этом блоге будут публиковаться новости, примеры, дополнительные материалы, статьи и все, что касается проекта. Также есть страничка проекта на Google Code, где можно найти свежай?ие версии исходников. Для связи с нами можете использовать комментарии к записям на этом блоге.
Поехали!

Александр Сергеев 

Дембцкий: ну почему Сергееву не понравился тот милый розовый скин с сердечками?

Рубрики: Новости | Комментарии (2) »