Длина дуги кривой безье

Вычисление опорных точек.

1323

pascal

procedure ToBezier(var A, B, C, D:TGPoint);

 function Point1(x1, x2, x3, x4:Single):Single;
 begin
    result := (-5*x1+18*x2-9*x3+2*x4)/6;
 end;

 function Point2(x1, x2, x3, x4:Single):Single;
 begin
    result := (2*x1-9*x2+18*x3-5*x4)/6;
 end;

var B, C : TGPoint;
begin
   Bx := Point1(A.x, B.x, C.x, D.x);
   By := Point1(A.y, B.y, C.y, D.y);
   Cx := Point2(A.x, B.x, C.x, D.x);
   Cy := Point2(A.y, B.y, C.y, D.y);
   B := B;
   C := C;
end;

pascal

var g : TGPGraphics;
    pen : TGPPen;
    brush : TGPSolidBrush;
    P : array  of TGPPointF;
    i : integer;
begin
   g := TGPGraphics.Create(image1.Canvas.Handle);
   pen := TGPPen.Create(aclBlack, 2);
   brush := TGPSolidBrush.Create(aclGreen);
   try
      g.SetSmoothingMode(SmoothingModeAntiAlias);

      P := makePoint(  10.0, 100);
      P := makePoint( 100.0, 150);
      P := makePoint( 180.0, 120);
      P := makePoint( 190.0,  20);

      for i := 1 to 4 do
         g.FillEllipse(brush, P.x-3, P.y-3, 6, 6);

      ToBezier(P, P, P, P);
      g.DrawBezier(pen, P, P, P, P);

      brush.SetColor(aclRed);
      for i := 2 to 3 do
         g.FillEllipse(brush, P.x-3, P.y-3, 6, 6);

      pen.SetWidth(1);
      pen.SetColor(aclBlue);
      for i := 1 to 3 do
         g.DrawLine(pen, P, P);

Конкретные случаи

Кривая А Безье определяется набором из контрольных точек P через Р п , где п называется порядок кривой ( п = 1 для линейных, 2 для квадратичной и т.д.). Первая и последняя контрольные точки всегда являются конечными точками кривой; однако промежуточные контрольные точки (если они есть) обычно не лежат на кривой. Суммы в следующих разделах следует понимать как то есть сумма коэффициентов равна 1.

Линейные кривые Безье

Для различных точек P и P 1 линейная кривая Безье — это просто прямая линия между этими двумя точками. Кривая задается

B(т)знак равноп+т(п1-п)знак равно(1-т)п+тп1, ≤т≤1{\ displaystyle \ mathbf {B} (t) = \ mathbf {P} _ {0} + t (\ mathbf {P} _ {1} — \ mathbf {P} _ {0}) = (1-t) \ mathbf {P} _ {0} + t \ mathbf {P} _ {1}, \ 0 \ leq t \ leq 1}

и эквивалентен линейной интерполяции .

Квадратичные кривые Безье

Квадратичная кривая Безье в струнном искусстве : конечные точки ( ) и контрольная точка ( × ) определяют квадратичную кривую Безье ( ).

Квадратичная кривая Безье — это путь, пройденный функцией B ( t ) для заданных точек P , P 1 и P 2 ,

B(т)знак равно(1-т)(1-т)п+тп1+т(1-т)п1+тп2, ≤т≤1{\ displaystyle \ mathbf {B} (t) = (1-t) + t , \ 0 \ leq t \ leq 1},

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

B(т)знак равно(1-т)2п+2(1-т)тп1+т2п2, ≤т≤1.{\ displaystyle \ mathbf {B} (t) = (1-t) ^ {2} \ mathbf {P} _ {0} +2 (1-t) t \ mathbf {P} _ {1} + t ^ {2} \ mathbf {P} _ {2}, \ 0 \ leq t \ leq 1.}

Это можно записать таким образом, чтобы подчеркнуть симметрию относительно P 1 :

B(т)знак равноп1+(1-т)2(п-п1)+т2(п2-п1), ≤т≤1.{\ displaystyle \ mathbf {B} (t) = \ mathbf {P} _ {1} + (1-t) ^ {2} (\ mathbf {P} _ {0} — \ mathbf {P} _ {1 }) + t ^ {2} (\ mathbf {P} _ {2} — \ mathbf {P} _ {1}), \ 0 \ leq t \ leq 1.}

Что сразу дает производную кривой Безье по t :

B′(т)знак равно2(1-т)(п1-п)+2т(п2-п1),{\ displaystyle \ mathbf {B} ‘(t) = 2 (1-t) (\ mathbf {P} _ {1} — \ mathbf {P} _ {0}) + 2t (\ mathbf {P} _ { 2} — \ mathbf {P} _ {1}),}

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

Вторая производная кривой Безье по t равна

B″(т)знак равно2(п2-2п1+п).{\ displaystyle \ mathbf {B} » (t) = 2 (\ mathbf {P} _ {2} -2 \ mathbf {P} _ {1} + \ mathbf {P} _ {0}).}

Кубические кривые Безье

Четыре точки P , P 1 , P 2 и P 3 на плоскости или в многомерном пространстве определяют кубическую кривую Безье. Кривая начинается в точке P 0 по направлению к P 1 и достигает точки P 3 в направлении P 2 . Обычно он не проходит через P 1 или P 2 ; эти точки служат только для получения информации о направлении. Расстояние между P 1 и P 2 определяет, «как далеко» и «насколько быстро» кривая перемещается к P 1 перед поворотом к P 2 .

Записывая B P i , P j , P k ( t ) для квадратичной кривой Безье, определенной точками P i , P j и P k , кубическая кривая Безье может быть определена как аффинная комбинация двух квадратичных кривых Безье:

B(т)знак равно(1-т)Bп,п1,п2(т)+тBп1,п2,п3(т), ≤т≤1.{\ displaystyle \ mathbf {B} (t) = (1-t) \ mathbf {B} _ {\ mathbf {P} _ {0}, \ mathbf {P} _ {1}, \ mathbf {P} _ {2}} (t) + t \ mathbf {B} _ {\ mathbf {P} _ {1}, \ mathbf {P} _ {2}, \ mathbf {P} _ {3}} (t), \ 0 \ leq t \ leq 1.}

Явный вид кривой:

B(т)знак равно(1-т)3п+3(1-т)2тп1+3(1-т)т2п2+т3п3, ≤т≤1.{\ Displaystyle \ mathbf {B} (т) = (1-т) ^ {3} \ mathbf {P} _ {0} +3 (1-т) ^ {2} т \ mathbf {P} _ {1 } +3 (1-t) t ^ {2} \ mathbf {P} _ {2} + t ^ {3} \ mathbf {P} _ {3}, \ 0 \ leq t \ leq 1.}

Для некоторых вариантов P 1 и P 2 кривая может пересекаться сама с собой или содержать острие .

Любую серию из 4 различных точек можно преобразовать в кубическую кривую Безье, которая проходит через все 4 точки по порядку. Учитывая начальную и конечную точки некоторой кубической кривой Безье и точки вдоль кривой, соответствующие t  = 1/3 и t  = 2/3, контрольные точки для исходной кривой Безье могут быть восстановлены.

Производная кубической кривой Безье по t равна

B′(т)знак равно3(1-т)2(п1-п)+6(1-т)т(п2-п1)+3т2(п3-п2).{\ displaystyle \ mathbf {B} ‘(t) = 3 (1-t) ^ {2} (\ mathbf {P} _ {1} — \ mathbf {P} _ {0}) + 6 (1-t ) t (\ mathbf {P} _ {2} — \ mathbf {P} _ {1}) + 3t ^ {2} (\ mathbf {P} _ {3} — \ mathbf {P} _ {2}) \ ,.}

Вторая производная кривой Безье по t равна

B″(т)знак равно6(1-т)(п2-2п1+п)+6т(п3-2п2+п1).{\ displaystyle \ mathbf {B} » (t) = 6 (1-t) (\ mathbf {P} _ {2} -2 \ mathbf {P} _ {1} + \ mathbf {P} _ {0 }) + 6t (\ mathbf {P} _ {3} -2 \ mathbf {P} _ {2} + \ mathbf {P} _ {1}) \ ,.}

Историческое прошлое

Плоский сплайн , физическое проявление сплайна в качестве математической концепции

До компьютеров проекты рисовались вручную на бумаге с помощью различных инструментов для рисования . Линейки использовались для прямых линий, циркуля для кругов и транспортира для углов. Но многие формы, такие как произвольная кривая носовой части корабля, не могли быть нарисованы с помощью этих инструментов. Хотя такие кривые можно было нарисовать от руки на чертежной доске, судостроителям часто требовалась версия в натуральную величину, которую нельзя было сделать вручную. Такие большие рисунки выполнялись с помощью гибких деревянных планок, называемых шлицами. Шлицы удерживались на месте в нескольких заранее определенных точках, называемых «утками»; Между утками эластичность материала шлицев заставляла полоску принимать форму, которая сводила к минимуму энергию изгиба, создавая, таким образом, максимально гладкую форму, соответствующую ограничениям. Форму можно было регулировать, перемещая уток.

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

Когда в процесс проектирования были внедрены компьютеры, были исследованы физические свойства таких шлицев, чтобы их можно было моделировать с математической точностью и воспроизводить там, где это необходимо. Пионерские работы были сделаны в Франции по Рено инженер Пьера Безье , и Citroën «s физик и математик Поль де Casteljau . Они работали почти параллельно друг другу, но поскольку Безье опубликовал результаты своей работы, кривые Безье были названы в его честь, а имя де Кастельжау связано только с соответствующими алгоритмами.

Сначала NURBS использовались только в собственных пакетах САПР автомобильных компаний. Позже они стали частью стандартных пакетов компьютерной графики.

Интерактивный рендеринг NURBS-кривых и поверхностей в реальном времени был впервые коммерчески доступен на рабочих станциях Silicon Graphics в 1989 году. В 1993 году первый интерактивный NURBS-моделлер для ПК, названный NöRBS, был разработан CAS Berlin, небольшой начинающей компанией, сотрудничающей с Технический университет Берлина .

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

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

Можно добавить кривую Безье третьего порядка к объекту с помощью метода с тремя параметрами или перегрузки с отдельными параметрами и :

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

  • Начальная точка: текущая точка в контуре или (0, 0), если не был вызван
  • Первая контрольная точка: в вызове
  • Вторая контрольная точка: в вызове
  • Конечная точка: в вызове

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

Лучший способ получить впечатление от кривой Безье третьего порядка — эксперименты. Это цель страницы кривой Безье , которая является производной от . В файле безиеркурвепаже. XAML создаются экземпляры и . Файл кода программной части безиеркурвепаже. XAML. CS создает четыре объекта в своем конструкторе. Обработчик событий создает объект для отрисовки кривой Безье на основе четырех объектов, а также рисует линии с точками по касательной от контрольных точек к конечным точкам:

Здесь он работает:

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

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

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

  • Вторая контрольная точка первой кривой
  • Конечная точка первой кривой, которая также является начальной точкой второй кривой
  • Первая контрольная точка второй кривой

В следующей статье по данным о пути SVGвы обнаружите средство для упрощения определения гладко Соединенных кривых Безье.

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

x (t) = (1 – t) ³ x ₀ + 3T (1 – t) ² x ₁ + 3T ² (1 – t) x ₂ + t ³ x ₃

y (t) = (1 – t) ³ y ₀ + 3T (1 – t) ² y ₁ + 3T ² (1 – t) y ₂ + t ³ y ₃

Наибольший показатель степени 3 подтверждает, что эти данные имеют значение в кубических полиномах. Очень просто проверить, что, если равно 0, точка — (x ₀, y ₀), то есть начальная точка, а если равно 1, то точка имеет значение (x ₃, y ₃), то есть конечная точка. Рядом с начальной точкой (для младших значений ) Первая контрольная точка (x ₁, y ₁) имеет усиленный результат, а ближе к конечной точке (большие значения ‘t ‘) вторая контрольная точка (x ₂, y ₂) имеет высокий результат.

Опорные точки

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

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

По двум точкам:

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

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

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

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

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

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

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

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

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

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

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

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

Как найти длину дуги кривой, если линия задана в полярной системе координат?

Пусть кривая  задана в полярных координатах уравнением , где , и при этом значение  определяет точку , а значение  – точку . Если на промежутке  функция  имеет непрерывную производную , то длина кривой  выражается следующей формулой:

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

Пример 6

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

Порядок и принципы решения точно такие же.

Используем формулу .

Найдём производную по «фи»:

Составим и максимально упростим подкоренное выражение:

Заливаем топливо:

…мда, презабавно, всё время понижали-понижали степень, а теперь её надо повысить. Используем формулу двойного угла  и основное тригонометрическое тождество , выцыганив тем самым заветный квадрат:

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

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

Таким образом, вынесение из-под корня проходит без всяких последствий. …Не хотел вам рассказывать об одном нехорошем методе решения, но таки поделюсь – всё равно догадаетесь, по себе знаю =) На черновике считаем  интеграл  и если получился отрицательный результат, то на чистовике ставим перед интегралом «минус». И никаких запарок с рассуждениями.

Ответ:

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

Успокоительная миниатюра для самостоятельного решения:

Пример 7

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

Хочется сказать ещё что-нибудь ласковое, но, к  сожалению, я тороплюсь, сегодня пятница и мне тоже хочется погулять =)

Желаю успехов!

Решения и ответы:

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

Пример 3: Решение: найдём производную: Таким образом:

(1) Используем тригонометрическую формулу (2) При вынесении из-под корня необходимо, чтобы подынтегральная функция осталась положительной:. Так как  на отрезке интегрирования, то: .(3) Данный интеграл разобран в Примере 18 статьи Сложные интегралы.Ответ

Пример 5: Решение: используем формулу .Найдём производные:Таким образом:Примечание:  при любом значении .Ответ

Пример 7: Решение: используем формулу:Ответ

(Переход на главную страницу)

Математика

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

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

Координаты кривой описываются в зависимости от параметра

  • Для двух точек:

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

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

Вместо нужно подставить координаты i-й опорной точки .

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

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

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

Основной подход


Аппроксимация несколькими линейными отрезками

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

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

Для некоторых кривых существует наименьшее число, которое является верхней границей длины любого полигонального приближения. Эти кривые называются выпрямляемыми, а количество определяется как длина дуги .
L{\ displaystyle L}L{\ displaystyle L}

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

Линейные кривые

Т в функции для линейной кривой Безье можно рассматривать как описывающие , как далеко Б ( т ) составляет от P до P 1 . Например, когда t = 0,25, B ( t ) составляет одну четверть пути от точки P до P 1 . Поскольку t изменяется от 0 до 1, B ( t ) описывает прямую линию от P до P 1 .

Анимация линейной кривой Безье, t в

Квадратичные кривые

Для квадратичных кривых Безье можно построить промежуточные точки Q и Q 1 такие, что при изменении t от 0 до 1:

  • Точка Q ( t ) изменяется от P до P 1 и описывает линейную кривую Безье.
  • Точка Q 1 ( t ) изменяется от P 1 до P 2 и описывает линейную кривую Безье.
  • Точка B ( t ) линейно интерполируется между Q ( t ) и Q 1 ( t ) и описывает квадратичную кривую Безье.

Построение квадратичной кривой Безье Анимация квадратичной кривой Безье, t в

Кривые высшего порядка

Соответственно, для кривых более высокого порядка требуется больше промежуточных точек. Для кубических кривых можно построить промежуточные точки Q , Q 1 и Q 2 , описывающие линейные кривые Безье, и точки R и R 1 , описывающие квадратичные кривые Безье:

Построение кубической кривой Безье Анимация кубической кривой Безье, t в

Для кривых четвертого порядка можно построить промежуточные точки Q , Q 1 , Q 2 и Q 3 , описывающие линейные кривые Безье, точки R , R 1 и R 2 , описывающие квадратичные кривые Безье, и точки S и S 1, которые описать кубические кривые Безье:

Построение кривой Безье четвертой степени Анимация кривой Безье четвертой степени, t в

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

Анимация кривой Безье пятого порядка, t в красным. Также показаны кривые Безье для каждого из нижних порядков.

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

Смещения (также известные как обводка) кривых Безье

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

В области векторной графики рисование двух симметрично разнесенных кривых смещения называется штриховкой (кривая Безье или вообще путь из нескольких сегментов Безье). Преобразование из смещенных кривых в заполненные контуры Безье имеет практическое значение при преобразовании шрифтов, определенных в Metafont , который позволяет обводить кривые Безье, в более широко используемые шрифты PostScript типа 1 , которые позволяют (в целях эффективности) только математически более простую операцию заполнение контура, определяемого (несамопересекающимися) кривыми Безье.

Базовые сведения

кривых Безье
pascal

var g : TGPGraphics;
    pen : TGPPen;
    brush : TGPBrush;
    P : array  of TGPPointF;
    i : integer;
begin
   g := TGPGraphics.Create(image1.Canvas.Handle);
   pen := TGPPen.Create(aclBlack, 2);
   brush := TGPSolidBrush.Create(aclGreen);
   try
      g.SetSmoothingMode(SmoothingModeAntiAlias);

      P := makePoint(  10.0, 100);
      P := makePoint(  60.0,  20);
      P := makePoint( 110.0, 180);
      P := makePoint( 160.0, 100);

      g.DrawBezier(pen, P, P, P, P);

      pen.SetWidth(1);
      pen.SetColor(aclBlue);
      g.DrawLine(pen, P, P);
      g.DrawLine(pen, P, P);

      for i := 1 to 4 do
         g.FillEllipse(brush, P.x-3, P.y-3, 6, 6);
   finally
      brush.free;
      pen.free;
      g.free;
   end;

Аппроксимация дуги эллипса кривыми Безье

pascal

function GetArcPoint(f, a, b:Single):TGPoint;
var n:integer;
    t, x, y, t2, a2, b2:Single;
begin
   n := GetQuadransRad(f);

   if abs(f-pi/2) < 0.001 then begin
      x := ; y := b;
   end else begin
      t := tan(f);
      t2 := t*t;
      b2 := b*b;
      a2 := a*a;
      x := sqrt((a2*b2) / (a2*t2+b2));
      y := x*t;
   end;
   case n of
      1 : begin x := +x; y := +y; end;
      2 : begin x := -x; y := +y; end;
      3 : begin x := -x; y := -y; end;
      4 : begin x := +x; y := -y; end;
   end;
   result.x := x;
   result.y := y;
end;

pascal

function GetQuadransRad(var a:Single):integer;
var n:integer;
begin
   if a > pi  then a := a - 2*pi;
   if a < -pi then a := a + 2*pi;

   n := ;
   if a >  then begin
      if (a >=  ) and (a <= pi/2)
      then n := 1
      else
      if (a >  pi/2) and (a <= pi) then begin
         n := 2; a := pi-a;
      end
   end else begin
      if (a <=   ) and (a >= -pi/2) then begin
         n := 4; a := -a;
      end else
      if (a <  -pi/2) and (a >= -pi  ) then begin
         n := 3; a := pi+a;
      end
   end;
   result := n;
end;

pascal

procedure GetArcBezier(rx, ry, start, sweep:Single;
                  var A, B, C, D:TGPoint); 
var f : Single;
    t1, t2, t3, t4 :Single;
begin
   f := start*pi/180;
   A := GetArcPoint(f, rx, ry);

   f := (start+sweep)*pi/180;
   D := GetArcPoint(f, rx, ry);

   t1 := arccos(A.x/rx); if A.y <  then t1 := -t1;
   t4 := arccos(D.x/rx); if D.y <  then t4 := -t4;
   if sweep >  then begin
      if t4 < t1 then t4 := t4+2*pi;
   end else begin
      if t4 > t1 then t4 := t4-2*pi;
   end;

   t2 := (t4-t1)/3 + t1;
   t3 := (t4-t1)/3*2 + t1;
   B.x := rx*cos(t2);
   B.y := ry*sin(t2);
   C.x := rx*cos(t3);
   C.y := ry*sin(t3);
   ToBezier(A, B, C, D);
end;

pascal

var g : TGPGraphics;
    pen : TGPPen;
    brush : TGPSolidBrush;
    Dt : TGPPointF;
    RX, RY : Single;
    A, B, C, D:TGPoint;
begin
   g := TGPGraphics.Create(image1.Canvas.Handle);
   pen := TGPPen.Create(aclBlack, 2);
   brush := TGPSolidBrush.Create(aclGreen);
   try
      g.SetSmoothingMode(SmoothingModeAntiAlias);

      RX := 180;
      RY := 80;
      Dt := makePoint(190.0, 90);

      // Исходный эллипс для сравнения
      pen.SetWidth(2);
      pen.SetColor(aclRed);
      g.DrawEllipse(pen, 10, 10, RX*2, RY*2);

      pen.SetWidth(3);
      pen.SetColor(aclBlack);
      GetArcBezier(rx, ry, 30, 60, A, B, C, D);
      g.DrawBezier(pen,
             A.x+Dt.x, A.y+Dt.y,
             B.x+Dt.x, B.y+Dt.y,
             C.x+Dt.x, C.y+Dt.y,
             D.x+Dt.x, D.y+Dt.y
             );

      pen.SetWidth(3);
      pen.SetColor(aclBlue);
      GetArcBezier(rx, ry, -30, -200, A, B, C, D);
      g.DrawBezier(pen,
             A.x+Dt.x, A.y+Dt.y,
             B.x+Dt.x, B.y+Dt.y,
             C.x+Dt.x, C.y+Dt.y,
             D.x+Dt.x, D.y+Dt.y
             );


pascal

function GetArcBezier(rx, ry, start, sweep:Single; 
    var Beziers : array of TGPoint):integer; overload;
var f:Single;
    i:integer;
begin
   result := ;
   if abs(sweep) > 360 then sweep := 360;
   if abs(sweep) < 1 then  exit;

   f := abs(sweep);
   if      f > 270 then result := 4
   else if f > 180 then result := 3
   else if f >  90 then result := 2
   else                 result := 1;

   f := sweep / result;
   for i :=  to result - 1 do begin
      GetArcBezier(rx, ry, start+f*i, f,
          Beziers,
          Beziers,
          Beziers,
          Beziers);
   end;
end;

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: