2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2, 3  След.
 
 Аппроксимация сплайна дугами окружностей
Сообщение05.07.2007, 08:51 


05/07/07
9
Ижевск
Здравствуйте, уважаемые участники форума!
Посоветуйте, пожалуйста, что-нибудь по такому вопросу. Нужно аппроксимировать заданный сплайн (в конкретном случае сглаживающий кубический, но хотелось бы получить решение для кубических сплайнов в общем случае) дугами окружностей и отрезками прямых.
Мне кажется, это можно сделать, разбив сегменты сплайна на участки в зависимости от кривизны и построив дуги по конечным точкам этих участков. Есть ли другие подходы к этой задаче? Как правильнее выбрать длину участков разбиения для сегмента и можно ли увеличить гладкость результата в точках сопряжения найденных дуг?

 Профиль  
                  
 
 
Сообщение05.07.2007, 08:59 
Супермодератор
Аватара пользователя


29/07/05
8248
Москва
Можно делать так: нанести на кривую точки через равные малые промежутки. Берем первые несколько точек, аппроксимируем, считаем, насколько велико получилось максимальное отклонение. Если меньше порога - добавляем следующую точку, снова аппроксимируем. Как только допустимый порог превышен, начинаем новую аппроксимацию.

 Профиль  
                  
 
 
Сообщение05.07.2007, 19:05 


05/07/07
9
Ижевск
PAV
Большое спасибо за идею! :D Сейчас займусь реализацией. Чтобы каждый раз все не пересчитывать, попробую отдельно рассчитывать максимально возможную длину для каждого следующего участка.

 Профиль  
                  
 
 
Сообщение05.07.2007, 19:05 
Заслуженный участник
Аватара пользователя


17/10/05
3709
:evil:
Поскольку каждый сегмент сплайна — это кривая Безье, то для сегмента существует классический алгоритм аппроксимации отрезками.

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

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

 Профиль  
                  
 
 
Сообщение05.07.2007, 19:37 


05/07/07
9
Ижевск
незваный гость
Спасибо! Сейчас почитала об этом алгоритме, понравилось - разбиение на определенное количество частей должно быть эффективным. После разбиения обязательно нужно будет объединить все, что можно, потому что нужны точные отрезки максимально возможной длины.

 Профиль  
                  
 
 
Сообщение06.07.2007, 08:34 
Супермодератор
Аватара пользователя


29/07/05
8248
Москва
После завершения аппроксимации (тем или иным способом) можно еще попытаться пошевелить в одну или другую стороны точки стыков различных участков аппроксимации, если при этом суммарная погрешность уменьшается.

 Профиль  
                  
 
 
Сообщение15.07.2007, 19:36 
Аватара пользователя


20/06/07
179
PAV писал(а):
После завершения аппроксимации (тем или иным способом) можно еще попытаться пошевелить в одну или другую стороны точки стыков различных участков аппроксимации, если при этом суммарная погрешность уменьшается.

Кстати, а вам здесь не пригодится ли оптимизация (координат точек стыков) при помощи генетического алгоритма с вещественным кодированием?
В качестве фитнесс-функции (цели оптимизации) можно взять суммарное среднеквадратическое отклонение (невязку) между исходным сплайном и его аппроксимацией.

 Профиль  
                  
 
 
Сообщение03.08.2007, 12:07 


29/09/06
4552
Поздно заметил сообщение, в ответ на которое мог бы, наверное, много порассказать. В плане аппроксимации именно окружностями. Но, если проблема разрешилась или вопрошающий ушёл, не буду... Приведу только пример так называемых бидуг (biarc curves), которые дают сопряжение двух линейных элементов --- точек $A$ и $B$ с наклонами касательных $\alpha$ и $\beta$ в этих точках. Имеется, как видно, одна степень свободы, можно минимизировать, например, скачок кривизны в точке сопряжения двух дуг.

Изображение

С "тридугами" можно делать всё что угодно...

update: 05.01.2011 - переместил картинку

 Профиль  
                  
 
 
Сообщение08.08.2007, 17:34 


05/07/07
9
Ижевск
Алексей К. писал(а):
Поздно заметил сообщение, в ответ на которое мог бы, наверное, много порассказать. В плане аппроксимации именно окружностями. Но, если проблема разрешилась или вопрошающий ушёл, не буду...

Нет, нет, я здесь, слежу за темой, и над методами аппроксимации продолжаю работать. Расскажите, пожалуйста.
Очень заинтересовали бидуги и тридуги - можно ли где-нибудь подробнее об этом почитать?

 Профиль  
                  
 
 
Сообщение08.08.2007, 18:50 


29/09/06
4552
Sunny писал(а):
Алексей К. писал(а):
Очень заинтересовали бидуги и тридуги - можно ли где-нибудь подробнее об этом почитать?


Да. Но поскольку мы вроде как никуда не спешим, приведу ссылки попозже. И они не будут электронными. Эти статьи будет трудно искать, они часто бесполезны, и проще порешать самому. Уж бидуги --- простая конструкция.

О бидугах написано очень много по-английски (журналы типа Computer-Aided Design итп.).
Это "очень много" --- практически одно и тоже, многократно повторенное.
Их открыли ради интерлояции окружностями.
По сути, задачка простая, и те мудрости, которые про неё пишут, простой плоскостной геометр быстро порешал бы.

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

Я её порешал когда-то, а термин "triac curve" мне был тогда незвестен.
Суть здесь в том, чтобы учитывать знак кривизны , и тогда вместо 8 решений будет только 2:
Мы ищем окружность (красненькую), которая гладко сопрягает зелёную и синюю. Мы видим на первом фрагменте 8 решений --- 8 сопрягающих окружностей заданного радиуса и незаданной ориентации. Но у зелёной и синей уже есть правильные направления, и про красную нам обычно известен знак кривизны (вал---отверстие), определяющий направление. И тогда решений только 2, помечены они как 1 и 2. В остальных 6 случаях имеем "антикасание" --- касательные имеют встречные, а не одинаковые направления.
Изображение

Ответил не полностью, совсем не затронул Вашу задачу. Но это попозже...

update: 05.01.2011 - переместил рисунки

 Профиль  
                  
 
 
Сообщение06.01.2009, 13:34 


06/01/09
1
Здравствуйте! А кто-нибудь мог бы объяснить поподробнее с чего вообще начинать аппроксимацию? Вот есть например кубический сплайн, построенный на 3 опорных точках.
У меня известны координаты только этих трёх точек... Т.е. я могу построить кривую.
А в чем заключается сама непосредственно аппроксимация? Я могу изменять длины отрезков или количество самих отрезков?

 Профиль  
                  
 
 Re: Аппроксимация сплайна дугами окружностей
Сообщение02.10.2010, 12:51 


29/09/06
4552
Надо же, оказывается, мне уже три года стыдно за этот должок. Пообещал и не сделал.
Но меня просят (через ЛС) развить тему, рассказать, что я знаю про эту задачу.
И я постараюсь довести это до ума.
Литературы в своём бумажном архиве я не нашёл. По жизни следил я за журналами CAD, CAGD, JCAM. Теперь журналов развелось много; и я уже почти не слежу. Гуглить можно "circular spline", "arc spline (approximation)".

Задачу, которую я намерен осветить, можно сформулировать так:
Найти кривую с кусочно-постоянной кривизной, аппроксимирующую заданную кривую $x(t),y(t)$ с заданной точностью.
Предлагаемое решение идёт чисто из моей головы; других (решений) не знаю. Результирующая кривая с кусочно-постоянной кривизной состоит, понятно, из гладко сопряжённых кусочков прямых и окружностей.

Так что речь идёт не только о сплайнах: $x(t),y(t)$ --- произвольная достаточно приличная кривая, о которой мы знаем или можем узнать всё. Из этого всего понадобятся наклон касательной $\tau(t)=\arctan(y'_t,x'_t)$, кривизна $k(t)=\dfrac{y''x'-x''y'}{({x'}^2+{y'}^2)^{3/2}}$ и решения уравнения $k'(t)=0$, т.е. экстремумы кривизны (вершины кривой). Функция $k(t)$ не обязана быть непрерывной.

Мы разбиваем кривую на достаточно малые отрезки-дуги следующим образом:
(1) выделяем вершины кривой; таким образом, кривизна на каждом участке будет монотонна, что впоследствии и позволит сгаранатировать точность аппроксимации;
(2) разбиение кривой внутри каждого участка должно быть как минимум таким, чтобы каждая дуга однозначно проектировалась на свою хорду (будет там внутри перегиб или нет --- нам до лампочки); уже на этом этапе мы сможем определить точность будущей аппроксимации и, если она недостаточна, вставить промежуточную точку.

Пункт (2) можно реализовать в виде сканированя кривой с неким мелким шагом $\Delta t$, с выбором очередного узла $t_i$ будущего circular spline исходя из наперёд заданной точности $\varepsilon$. Замечу, что нам не нужны точки перегиба кривой и узлы оригинального сплайна.

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

Изображение

а) Заданная кривая, представленная мелкими точечками, --- спираль Корню. У неё, как известно, нет вершин: кривизна --- линейная функция длины дуги. Поэтому первый этап разбиения отменяется, и мы начали со второго. Выбрали 11 точек, соблюдя условие однозначного проектирования на хорду.

b) Серенькие области --- некие оценки точности интерполяции/аппроксимации (повторяю --- это некий другой алгоритм). Здесь важно то, что монотонность кривизны не позволяет никакой аппроксимирующей кривой (тоже с возрастающей или тоже с убывающей кривизной, с некими граничными условиями на закреплённых концах) выйти за эти пределы.

c) Количество узлов увеличено с 11 до 15. При увеличении количества точек в n раз ширина области уменьшается в n^3 раз.

Писать буду по частям: так мне психически проще. Это была интродукция; вопрошавшие пусть видят, что я начал отвечать.

update: 05.01.2011 - переместил рисунок

 Профиль  
                  
 
 Граничные условия на участке аппрксимации.
Сообщение03.10.2010, 13:55 


29/09/06
4552
Рассмотрим теперь один участок нашего разбиения.

Две соседние точки обозначим $(x_1,y_1,\tau_1,k_1)$ и $(x_2,y_2,\tau_2,k_2)$; к координатам мы присовокупили известные наклоны касательных и кривизны. Пусть длина и наклон хорды равны $$2c=\sqrt{(x_2-x_1)^2+(y_2-y_1)^2}\text{~~~и~~~}\mu=\arctan(y_2-y_1,x_2-x_1).$$
Рассмотрим этот участок в локальной системе координат, в которой точка $(x_1,y_1)$ превращается в точку $A=(-c,0)$, а точка $(x_2,y_2)$ --- в точку $B=(c,0)$. Вычисляя наклоны касательных в этой системе координат, $\alpha=\tau_1-\mu,\quad\beta=\tau_2-\mu$, надо привести их к интервалу $(-\pi,\pi)$ (равенство (1) это, естественно, предполагает).

\begin{picture}(400,200)
\linethickness{1.1pt}\qbezier(0,0)(200,0)(400,0)
\qbezier(400,0)(400,100)(400,200)
\qbezier(400,200)(200,200)(0,200)
\qbezier(0,200)(0,100)(0,0)

\linethickness{0.6pt}
\qbezier(130,196)(129,196)(129,196)
\qbezier(130,196)(129,196)(129,196)
\qbezier(130,196)(129,196)(129,196)
\qbezier(129,196)(129,198)(130,200)
\qbezier(130,200)(131,198)(132,196)
\qbezier(132,196)(131,196)(130,197)
\put(134,193){$y$}
\linethickness{0.6pt}\qbezier(397,100)(396,101)(395,102)
\qbezier(395,102)(398,101)(400,100)
\qbezier(400,100)(398,100)(395,99)
\qbezier(395,99)(396,100)(397,100)
\put(393,91){$x$}
\linethickness{0.6pt}\qbezier(130,0)(130,99)(130,197)
\qbezier(0,100)(199,100)(397,100)

\linethickness{0.4pt}\qbezier(0,0)(200,0)(400,0)
\qbezier(400,0)(400,100)(400,200)
\qbezier(400,200)(200,200)(0,200)
\qbezier(0,200)(0,100)(0,0)
\put(30,86){$A$}\put(224,87){$B$}\color{red}

\linethickness{1.1pt}\qbezier(394,21)(388,20)(381,20)
\qbezier(381,20)(375,21)(369,21)
\qbezier(369,21)(362,22)(356,23)
\qbezier(356,23)(350,25)(344,27)
\qbezier(344,27)(338,29)(332,31)
\qbezier(332,31)(326,34)(320,37)
\qbezier(320,37)(315,40)(309,43)
\qbezier(309,43)(303,46)(298,49)
\qbezier(298,49)(293,53)(287,56)
\qbezier(287,56)(282,60)(277,64)
\qbezier(277,64)(272,68)(267,71)
\qbezier(267,71)(262,75)(257,79)
\qbezier(257,79)(252,83)(247,87)
\qbezier(247,87)(242,91)(237,95)
\qbezier(237,95)(232,99)(227,103)
\qbezier(227,103)(222,107)(217,111)
\qbezier(217,111)(211,114)(206,118)
\qbezier(206,118)(201,121)(196,125)
\qbezier(196,125)(190,128)(185,131)
\qbezier(185,131)(179,134)(173,137)
\qbezier(173,137)(167,140)(161,142)
\qbezier(161,142)(155,144)(149,146)
\qbezier(149,146)(143,148)(137,149)
\qbezier(137,149)(131,150)(124,151)
\qbezier(124,151)(118,151)(112,152)
\qbezier(112,152)(105,151)(99,151)
\qbezier(99,151)(93,149)(86,148)
\qbezier(86,148)(80,146)(74,144)
\qbezier(74,144)(69,141)(63,138)
\qbezier(63,138)(58,135)(53,131)
\qbezier(53,131)(48,127)(43,122)
\qbezier(43,122)(40,117)(36,112)
\qbezier(36,112)(33,106)(30,100)
\qbezier(30,100)(29,94)(27,88)
\qbezier(27,88)(27,82)(26,75)
\qbezier(26,75)(27,69)(28,63)
\qbezier(28,63)(30,57)(33,51)
\qbezier(33,51)(36,46)(40,40)
\qbezier(40,40)(44,36)(49,32)
\qbezier(49,32)(54,28)(60,25)
\qbezier(60,25)(66,24)(72,22)
\qbezier(72,22)(79,22)(85,22)
\qbezier(85,22)(91,24)(97,26)
\qbezier(97,26)(103,29)(108,32)
\color{blue}
\put(53,132){\circle*{5}}\put(88,149){\circle*{5}}\put(127,151){\circle*{5}}\put(164,141){\circle*{5}}\put(189,129){\circle*{5}}\put(30,100){\circle*{5}}\put(230,100){\circle*{5}}
\linethickness{0.4pt}\qbezier(30,100)(42,123)(61,139)
\qbezier(61,139)(81,154)(106,160)
\qbezier(106,160)(130,166)(155,160)
\qbezier(155,160)(180,154)(199,139)
\qbezier(199,139)(219,123)(230,100)

\linethickness{0.4pt}\qbezier(30,100)(46,127)(73,142)
\qbezier(73,142)(100,157)(130,157)
\qbezier(130,157)(161,157)(188,142)
\qbezier(188,142)(214,127)(230,100)

\linethickness{0.4pt}\qbezier(30,100)(48,124)(74,138)
\qbezier(74,138)(101,151)(130,151)
\qbezier(130,151)(160,151)(186,138)
\qbezier(186,138)(213,124)(230,100)

\linethickness{0.4pt}\qbezier(30,100)(50,122)(76,134)
\qbezier(76,134)(102,145)(130,145)
\qbezier(130,145)(159,145)(185,134)
\qbezier(185,134)(211,122)(230,100)

\linethickness{0.4pt}\qbezier(30,100)(57,127)(94,137)
\qbezier(94,137)(130,146)(167,137)
\qbezier(167,137)(203,127)(230,100)
\color{black}
\put(84,135){$P$}
\linethickness{1.1pt}\qbezier(30,100)(40,125)(59,143)
\qbezier(59,143)(79,160)(105,167)
\qbezier(105,167)(130,173)(156,167)
\qbezier(156,167)(182,160)(201,143)
\qbezier(201,143)(221,125)(230,100)

\linethickness{1.1pt}\qbezier(56,170)(54,169)(53,169)
\qbezier(53,169)(56,172)(58,175)
\qbezier(58,175)(58,171)(58,167)
\qbezier(58,167)(57,168)(56,170)
\put(57,179){$\alpha$}
\linethickness{1.1pt}\qbezier(30,100)(43,135)(56,170)

\linethickness{1.1pt}\qbezier(30,100)(59,123)(95,131)
\qbezier(95,131)(130,139)(166,131)
\qbezier(166,131)(201,123)(230,100)

\linethickness{1.1pt}\qbezier(305,43)(305,45)(305,46)
\qbezier(305,46)(307,43)(309,39)
\qbezier(309,39)(305,40)(301,42)
\qbezier(301,42)(303,42)(305,43)
\put(309,24){$\beta$}
\linethickness{1.1pt}\qbezier(230,100)(267,72)(305,43)
\end{picture}

На рисунке красную аппроксимируемую кривую ограничивает линза: одна её дуга (в этом примере --- верхняя ) идёт из $A$ в $B$, касаясь кривой в начальной точке. Вторая граница линзы идёт из $A$ в $B$, касаясь кривой в конечной точке. (Верхняя и нижняя поменяются местами в случае убывающей кривизны, $k_1>k_2$).

Теперь будем двигать точечку $P$ из $A$ в $B$ вдоль нашей кривой. Для каждого её положения построим дугу $APB$. Понятно, что в предельных положениях $P=A$ и $P=B$ эти дуги совпадают с границами линзы. Можно доказать, что если кривизна кривой изменяется монотонно, то дуги $APB$ при этом движении "монотонно" заполнят линзу. Любая кривая с монотонной кривизной и данными граничными условиями $(-c,0,\alpha,k_1)$, $(c,0,\beta,k_2)$ сидит в этой линзе. (Любая --- в смысле ещё и однозначного проектирования на хорду; это условие можно ослабить, но...) Ширина линзы --- $$W=c\left|\tg\frac\alpha 2+\tg\frac\beta 2\right|.$$ Это и есть гарантированная точность нашей будущей аппроксимации. А в роли кривой с монотонной кривизной, которой мы подменим нашу заданную кривую (Безью, Корню, etc), выступит бидуга, описанная несколько выше.

Заметим, что если $\beta=-\alpha$, то мы получаем линзу нулевой ширины. Единственная кривая с монотонной(=постоянной) кривизной, удовлетворяющая таким граничным условиям, есть дуга окружности ($k_2=k_1$). И вообще, $$\mathrm{sign}\,(\alpha+\beta)=\mathrm{sign}(k_2-k_1)\qquad\qquad\eqno(1)$$(Vogt W., Über monotongekrümmte Kurven, J. reine und angew. Math., 144, 1914, 239--248, Satz 12).

-- 03 окт 2010, 15:07 --

Ничего не изменится, если в процессе возрастания/убывания кривизны случится перегиб (кривизна изменит знак):

\begin{picture}(400,200)
\linethickness{1.1pt}\qbezier(0,0)(200,0)(400,0)
\qbezier(400,0)(400,100)(400,200)
\qbezier(400,200)(200,200)(0,200)
\qbezier(0,200)(0,100)(0,0)

\linethickness{0.6pt}\qbezier(130,197)(129,196)(129,196)
\qbezier(129,196)(129,198)(130,200)
\qbezier(130,200)(131,198)(132,196)
\qbezier(132,196)(131,196)(130,197)
\put(134,193){$y$}
\linethickness{0.6pt}\qbezier(397,100)(396,101)(395,102)
\qbezier(395,102)(398,101)(400,100)
\qbezier(400,100)(398,100)(395,99)
\qbezier(395,99)(396,100)(397,100)
\put(393,91){$x$}
\linethickness{0.6pt}\qbezier(130,0)(130,99)(130,197)
\qbezier(0,100)(199,100)(397,100)

\linethickness{0.4pt}\qbezier(0,0)(200,0)(400,0)
\qbezier(400,0)(400,100)(400,200)
\qbezier(400,200)(200,200)(0,200)
\qbezier(0,200)(0,100)(0,0)
\put(30,86){$A$}\put(224,87){$B$}\color{red}

\linethickness{1.1pt}\qbezier(261,190)(264,187)(268,184)
\qbezier(268,184)(271,180)(274,176)
\qbezier(274,176)(276,172)(278,168)
\qbezier(278,168)(279,163)(280,159)
\qbezier(280,159)(280,154)(280,149)
\qbezier(280,149)(279,144)(278,140)
\qbezier(278,140)(276,135)(274,131)
\qbezier(274,131)(271,127)(269,123)
\qbezier(269,123)(265,120)(262,116)
\qbezier(262,116)(258,113)(254,110)
\qbezier(254,110)(250,108)(246,106)
\qbezier(246,106)(242,104)(237,102)
\qbezier(237,102)(233,101)(228,100)
\qbezier(228,100)(223,99)(219,98)
\qbezier(219,98)(214,98)(209,98)
\qbezier(209,98)(204,98)(199,98)
\qbezier(199,98)(195,99)(190,99)
\qbezier(190,99)(185,100)(181,101)
\qbezier(181,101)(176,101)(171,102)
\qbezier(171,102)(167,103)(162,105)
\qbezier(162,105)(157,106)(153,107)
\qbezier(153,107)(148,108)(144,109)
\qbezier(144,109)(139,111)(134,112)
\qbezier(134,112)(130,113)(125,114)
\qbezier(125,114)(120,115)(116,116)
\qbezier(116,116)(111,117)(106,118)
\qbezier(106,118)(102,118)(97,119)
\qbezier(97,119)(92,119)(87,119)
\qbezier(87,119)(83,119)(78,119)
\qbezier(78,119)(73,118)(68,118)
\qbezier(68,118)(64,117)(59,116)
\qbezier(59,116)(55,114)(50,113)
\qbezier(50,113)(46,111)(41,108)
\qbezier(41,108)(38,106)(34,103)
\qbezier(34,103)(30,100)(27,97)
\qbezier(27,97)(24,93)(21,89)
\qbezier(21,89)(19,85)(16,81)
\qbezier(16,81)(15,76)(14,71)
\qbezier(14,71)(13,67)(13,62)
\qbezier(13,62)(13,57)(14,53)
\qbezier(14,53)(16,48)(17,44)
\qbezier(17,44)(20,40)(22,36)
\qbezier(22,36)(26,33)(30,29)
\qbezier(30,29)(34,27)(38,25)
\color{blue}
\put(61,116){\circle*{5}}\put(95,119){\circle*{5}}\put(129,113){\circle*{5}}\put(162,105){\circle*{5}}\put(189,99){\circle*{5}}\put(30,100){\circle*{5}}\put(230,100){\circle*{5}}
\linethickness{0.4pt}\qbezier(30,100)(60,120)(95,127)
\qbezier(95,127)(130,133)(165,127)
\qbezier(165,127)(200,120)(230,100)

\linethickness{0.4pt}\qbezier(30,100)(78,121)(130,121)
\qbezier(130,121)(183,121)(230,100)
\linethickness{0.4pt}\qbezier(30,100)(130,126)(230,100)
\linethickness{0.4pt}\qbezier(30,100)(130,110)(230,100)
\linethickness{0.4pt}\qbezier(30,100)(130,97)(230,100)
\color{black}
\put(91,105){$P$}
\linethickness{1.1pt}\qbezier(30,100)(58,125)(94,135)
\qbezier(94,135)(130,144)(167,135)
\qbezier(167,135)(203,125)(230,100)

\linethickness{1.1pt}\qbezier(85,150)(83,151)(82,151)
\qbezier(82,151)(86,153)(90,154)
\qbezier(90,154)(88,151)(86,147)
\qbezier(86,147)(85,148)(85,150)
\put(89,158){$\alpha$}
\linethickness{1.1pt}\qbezier(30,100)(58,125)(85,150)

\linethickness{1.1pt}\qbezier(30,100)(130,77)(230,100)

\linethickness{1.1pt}\qbezier(322,122)(320,123)(319,124)
\qbezier(319,124)(323,124)(328,123)
\qbezier(328,123)(324,121)(321,118)
\qbezier(321,118)(321,120)(322,122)
\put(330,120){$\beta$}
\linethickness{1.1pt}\qbezier(230,100)(276,111)(322,122)
\end{picture}

 Профиль  
                  
 
 Re: Аппроксимация сплайна дугами окружностей
Сообщение03.10.2010, 20:54 


29/09/06
4552
Пусть бидуга $ATB$ имеет наклоны касательных на концах $\alpha,\beta$; кривизны двух её участков, $AT$ и $TB$, равны $q_1$ и $q_2$ . При этом, очевидно, мы можем выбрать свободно одну из кривизн. Вторая однозначно определяется уравнением $$(q_1c+\sin\alpha)(q_2c-\sin\beta)+\sin^2\dfrac{\alpha+\beta}2=0.$$
Иными словами, при данных граничных углах мы можем параметризовать семейство бидуг, например, следующим образом:
$$
     q_1(p)=    -\frac1c\left(\sin\alpha +\dfrac1p \sin\omega\right),\qquad  
     q_2(p)=\frac1c\left(\sin\beta +  p{}\,\sin\omega\right),
      \qquad\text{где}\quad  \omega=\dfrac{\alpha{+}\beta}{2}.
$$
Тогда координаты точки касания $T$ двух дуг определяются так: $$
 X_T= c\,\dfrac{p^2-1}{p^2+2p\cos\gamma+1},\quad
 Y_T= c\,\dfrac{2p\sin\gamma}{p^2+2p\cos\gamma+1},
 \qquad\text{где}\quad \gamma=\dfrac{\alpha{-}\beta}{2}.\quad\eqno(2)$$ Пригодится и наклон касательной к бидуге в точке сопряжения $T$: $$
 \begin{array}{l}  
    \cos\tau_{_T} =\hphantom{-}\dfrac{p^2\cos\alpha + 2p\cos\omega + \cos\beta}{p^2+2p\cos\gamma+1},
    \\[6pt]
    \sin\tau_{_T} =-\dfrac{p^2\sin\alpha + 2p\sin\omega + \sin\beta}{p^2+2p\cos\gamma+1},
 \end{array}
 \quad
    \tan\dfrac{\tau_{_T}}{2}={-}\dfrac%
    {p\sin\frac{\alpha}2+\sin\frac{\beta}2}
    {p\cos\frac{\alpha}2+\cos\frac{\beta}2}\,.\quad\eqno(3)$$ Бидуги с $0<p<\infty$ будут располагаться внутри линзы (бидуги с $p=0$ и $p=\infty$ легко проассоциировать с границами линзы).

Для построения аппроксимирующей кривой можно выбрать любое значение $p>0$. Так, $p=1$ даст бидугу с точкой сопряжения "посредине" (на локальной оси ординат). Рекомендую, однако, использовать значения граничных кривизн $k_{1,2}$ нашей заданной кривой, и выбрать $p$ в пределах $p_1\le p\le p_2$, где $$p_1=\frac{-\sin\omega}{k_1c+\sin\alpha},\qquad
p_2=\frac{k_2c-\sin\beta}{\sin\omega}$$ (эти значения получены из уравнений $q_1(p_1)=k_1$ и $q_2(p_2)=k_2$). Например, взять $$p=\sqrt{p_1p_2}.$$ Такой выбор связан с тем, что имеется более жёсткая граница на расположение кривых с монотонной кривизной.
Для кривых с $-\infty\le k(t)\le+\infty$ такой границей является вышеупомянутая линза.
Для кривых с $k_1\le k(t)\le k_2$ границу можно сузить до более сложной конструкции (зелёненькой):

\begin{picture}(232,176)
\linethickness{0.4pt}\qbezier(0,0)(116,0)(232,0)
\qbezier(232,0)(232,88)(232,176)
\qbezier(232,176)(116,176)(0,176)
\qbezier(0,176)(0,88)(0,0)
\linethickness{0.6pt}\qbezier(213,72)(212,73)(212,74)
\qbezier(212,74)(214,73)(216,72)
\qbezier(216,72)(214,72)(212,71)
\qbezier(212,71)(212,72)(213,72)
\linethickness{0.6pt}\qbezier(4,72)(109,72)(213,72)
\put(13,60){$A$}\put(172,60){$B$}
\linethickness{1.1pt}\qbezier(16,72)(18,93)(29,110)
\qbezier(29,110)(41,126)(58,136)
\qbezier(58,136)(76,146)(96,146)
\qbezier(96,146)(117,146)(135,136)
\qbezier(135,136)(152,126)(163,110)
\qbezier(163,110)(175,93)(176,72)
\linethickness{1.1pt}\qbezier(21,122)(19,121)(18,120)
\qbezier(18,120)(20,124)(21,128)
\qbezier(21,128)(23,124)(24,120)
\qbezier(24,120)(22,121)(21,122)
\put(20,132){$\alpha$}
\linethickness{1.1pt}\qbezier(16,72)(19,97)(21,122)
\linethickness{1.1pt}\qbezier(16,72)(38,94)(67,102)
\qbezier(67,102)(96,109)(126,102)
\qbezier(126,102)(155,94)(176,72)
\linethickness{1.1pt}\qbezier(212,37)(212,39)(212,41)
\qbezier(212,41)(214,37)(216,33)
\qbezier(216,33)(212,35)(208,36)
\qbezier(208,36)(210,37)(212,37)
\put(220,28){$\beta$}
\linethickness{1.1pt}\qbezier(176,72)(194,55)(212,37)
\color{green}
\linethickness{1.3pt}\qbezier(53,115)(52,116)(51,118)
\qbezier(51,118)(56,117)(61,116)
\qbezier(61,116)(56,113)(52,111)
\qbezier(52,111)(53,113)(53,115)
\linethickness{1.3pt}\qbezier(16,72)(18,84)(24,94)
\qbezier(24,94)(30,103)(39,109)
\qbezier(39,109)(45,113)(52,114)
\qbezier(52,114)(53,115)(53,115)
\qbezier(132,116)(155,94)(176,72)
\linethickness{1.3pt}\qbezier(127,120)(127,123)(127,125)
\qbezier(127,125)(130,120)(132,116)
\qbezier(132,116)(127,118)(123,119)
\qbezier(123,119)(125,120)(127,120)
\linethickness{0.4pt}\qbezier(16,72)(18,88)(26,102)
\qbezier(26,102)(34,115)(47,124)
\qbezier(47,124)(60,132)(76,134)
\qbezier(76,134)(91,136)(106,132)
\qbezier(106,132)(121,127)(132,116)
\qbezier(61,116)(93,118)(123,107)
\qbezier(123,107)(153,95)(176,72)
\color{black}
\put(59,103){$T_1$}\put(134,118){$T_2$}\color{magenta}
\linethickness{0.8pt}
\qbezier(92,115)(94,114)(97,115)
\qbezier(97,115)(99,116)(101,118)
\qbezier(101,118)(103,120)(103,123)
\qbezier(103,123)(103,126)(102,128)
\qbezier(102,128)(101,131)(99,132)
\qbezier(99,132)(97,134)(94,134)
\qbezier(94,134)(92,135)(89,134)
\qbezier(89,134)(87,133)(85,131)
\qbezier(85,131)(84,128)(83,126)
\qbezier(83,126)(83,123)(84,121)
\qbezier(84,121)(85,118)(87,117)
\qbezier(87,117)(89,115)(92,115)
\color{black}
\linethickness{0.4pt}\qbezier(232,0)(348,0)(464,0)
\qbezier(464,0)(464,88)(464,176)
\qbezier(464,176)(348,176)(232,176)
\qbezier(232,176)(232,88)(232,0)
\linethickness{0.6pt}\qbezier(445,72)(444,73)(443,74)
\qbezier(443,74)(446,73)(448,72)
\qbezier(448,72)(446,72)(443,71)
\qbezier(443,71)(444,72)(445,72)

\linethickness{0.6pt}\qbezier(236,72)(340,72)(445,72)
\put(244,60){$A$}\put(404,77){$B$}
\linethickness{1.1pt}\qbezier(248,72)(271,91)(300,98)
\qbezier(300,98)(328,105)(357,98)
\qbezier(357,98)(386,91)(408,72)
\linethickness{1.1pt}\qbezier(287,105)(285,105)(283,106)
\qbezier(283,106)(287,107)(291,108)
\qbezier(291,108)(289,105)(287,101)
\qbezier(287,101)(287,103)(287,105)
\put(290,112){$\alpha$}
\linethickness{1.1pt}\qbezier(248,72)(267,88)(287,105)
\linethickness{1.1pt}\qbezier(248,72)(271,54)(300,47)
\qbezier(300,47)(328,40)(357,47)
\qbezier(357,47)(386,54)(408,72)

\linethickness{1.1pt}\qbezier(446,105)(445,105)(443,106)
\qbezier(443,106)(447,107)(451,108)
\qbezier(451,108)(449,105)(447,101)
\qbezier(447,101)(447,103)(446,105)
\put(455,103){$\beta$}
\linethickness{1.1pt}\qbezier(408,72)(427,88)(446,105)
\color{green}
\linethickness{1.3pt}\qbezier(296,76)(296,79)(296,81)
\qbezier(296,81)(299,77)(302,72)
\qbezier(302,72)(297,74)(292,75)
\qbezier(292,75)(294,76)(296,76)
\linethickness{1.3pt}\qbezier(248,72)(256,79)(265,81)
\qbezier(265,81)(275,83)(285,81)
\qbezier(285,81)(290,80)(295,77)
\qbezier(295,77)(295,77)(296,76)
\qbezier(355,72)(362,66)(372,64)
\qbezier(372,64)(382,62)(391,64)
\qbezier(391,64)(401,66)(408,72)
\linethickness{1.3pt}\qbezier(349,77)(349,79)(349,81)
\qbezier(349,81)(352,77)(355,72)
\qbezier(355,72)(350,74)(345,75)
\qbezier(345,75)(347,76)(349,77)
\linethickness{0.4pt}
\linethickness{0.4pt}\qbezier(248,72)(263,85)(282,90)
\qbezier(282,90)(302,94)(321,90)
\qbezier(321,90)(339,85)(354,73)
\qbezier(302,72)(317,60)(336,55)
\qbezier(336,55)(355,51)(374,55)
\qbezier(374,55)(393,60)(408,72)
\color{black}
\put(295,61){$T_1$}\put(357,75){$T_2$}\color{magenta}
\linethickness{0.8pt}
\qbezier(321,60)(325,59)(328,59)
\qbezier(328,59)(332,59)(335,62)
\qbezier(335,62)(338,64)(340,67)
\qbezier(340,67)(341,71)(341,74)
\qbezier(341,74)(340,78)(338,81)
\qbezier(338,81)(336,84)(333,86)
\qbezier(333,86)(329,87)(325,87)
\qbezier(325,87)(322,87)(319,84)
\qbezier(319,84)(316,82)(314,79)
\qbezier(314,79)(313,75)(313,72)
\qbezier(313,72)(313,68)(316,65)
\qbezier(316,65)(318,62)(321,60)
\end{picture}

Дуга $AT_1$, часть бидуги $AT_1B$, имеет кривизну $k_1$, ту самую, что и наша оригинальная кривая в точке $A$.
Дуга $T_2B$, часть бидуги $AT_2B$, имеет кривизну $k_2$, ту самую, что и наша оригинальная кривая в точке $B$.
Область между этими двумя бидугами (их параметры --- $p_1$ и $p_2$) и есть эта более жёсткая граница. Неулучшаемая.
Её ширина, т.е. диаметр наибольшей вписанной окружности, равна $$\varnothing=
 \dfrac{4c(p_2-p_1)\sin|\omega|}
       {\sqrt{-4(p_2\sin\alpha+\sin\omega)(\sin\beta+p_1\sin\omega)(p_2-p_1) +(1{+}2p_2\cos\gamma{+}p_1p_2)^2}+|1{+}2p_2\cos\gamma{+}p_1p_2|}.$$
Найденную по формулам (2), (3) новую промежуточную точку следует теперь обратным преобразованием вернуть в изначальную систему координат: $(x_T,y_T)\to(x_{12},y_{12})$. Для наклона касательной преобразование имеет вид $\tau_{12}=\tau_T+\mu$. Мы таким образом в имевшееся разбиение $(x_i,y_i,\tau_i),\quad i=1,\ldots,N$ навставляли аналогичных промежуточных точек. Новая конструкция вполне описывается новой последовательностью $$
(x_1,y_1,\tau_1),\quad (x_2,y_2,\tau_2),\quad (x_3,y_3,\tau_3),\ldots\,.$$ При восстановлении кривой по этим данным мы для любой $i$-той точки строим дугу окружности, выходящую из неё под углом $\tau_i$ и приходящую в точку $(x_{i+1},y_{i+1})$. Такая дуга единственна и неповторима.

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

 Профиль  
                  
 
 Re: Аппроксимация сплайна дугами окружностей
Сообщение04.10.2010, 13:08 


29/09/06
4552
У кривых Безье (и, соответственно, кубических сплайнов) задача выделения вершин --- самая противная (по сравнению, скажем, с большинством классических кривых). Она сводится к уравнению 5-й степени. Одним программистам это --- раз плюнуть, другие --- морщатся и фыркают. Уравнение легко выписывается явно, ежели кривую сунуть в какое-то "каноническое" положение. Например, в ту же локальную систему координат, в которой я чуть выше возился, или выпустить её из начала координат вдоль оси абсцисс. Т.е. в переменных, не зависящих, от системы координат (длины, углы поворота узлов контрольного полигона).
Для сплайна, естественно, надо ещё проверить, не работает ли сам узел как вершина.

Ну и осталось у меня c каких-то давних пор впечатление, что на кривых Безье вечно какие-то "ненужные" вершины появляются.
Вместо кривизны типа \begin{picture}(60,40)\color{green}\qbezier(0,0)(10,30)(30,30)\qbezier(30,30)(40,30)(60,40)\end{picture} появится какая-нибудь гадость вроде \begin{picture}(60,40)\color{red}\qbezier(0,0)(20,36)(30,30)\qbezier(30,30)(40,24)(60,40)\end{picture} с двумя вершинами.
Возможно, мы обошлись бы парочкой аппроксимирующих круговых дуг, а вынуждены шесть делать на трёх участках монотонности. Какие-то соображения по вопросу "Нельзя ли этими вершинками пренебречь?", т.е. по оценке "значимости" вершины, у меня имеются, но недосоображённые.

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

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 38 ]  На страницу 1, 2, 3  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: Serg53


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group