Опубликован: 27.12.2010 | Уровень: специалист | Доступ: платный
Лекция 6:

Кривые и поверхности в компьютерной геометрии, II

Усеченная степенная функция

Пусть m \ge 0 - целое число. Рассмотрим функцию \sigma_m(z,t) = ( max(0, z -t) )^m. При фиксированном t функция \sigma_m(z,t), рассматриваемая как функция z, называется усеченной степенной функцией.

Лемма 6.1. Для производных усеченной степенной функции справедливы формулы

\frac{d^k \sigma_m}{dz^k}=\frac{m!}{(m-k)!}\sigma_{m-k}, \frac{d^k \sigma_m}{dt^k}=\frac{(-1)^km!}{(m-k)!}\sigma_{m-k}, k=1, \dots, m

Обозначим через f[t_1,\dots, t_k] разделенную разность порядка (k-1) функции f(x) , построенную по узлам t_1,\dots, t_k. Фиксируем набор узлов t_0 < t_1 \lt; \dots < t_m и рассмотрим функцию M(t) =\sigma_{m-1}[t_0, \dots, t_m](t) , где разделенная разность \sigma_{m-1}[t_0, \dots , t_m]( t ) вычисляется от \sigma_{m-1}(z,t) , рассматриваемой как функция z при фиксированном t.

Лемма 6.2. Пусть m > 0. Тогда M(t) = 0, если t\le t_0 или t \ge t_m.

Замечание 6.1.1. Из леммы 6.2 вытекает, что \sigma_{m-1}[t_0, \dots  ,t_m](t) является непрерывной при m \ge 2 функцией параметра t, отличной от нуля лишь на (t_0,t_m) .

Пример 6.1.2. Разделенная разность пятого порядка усеченной кубической функции. Разделенная разность вычисляется от \sigma_m(z,t) , рассматриваемой как функция z при фиксированном t. Программа демонстрирует равенство нулю разделенной разности при всех t, лежащих левее и правее всех узлов.

In[2]:=f[t_, z_]:=If[t < z, (z-t)^3, 0];
            Plot[f[-6, z], {z, -20, 20}]

In[4] :=DynamicModule[ {h, z, t, st, M, G, i, x, y} , 
              h[x_, y_] : = If [x < y, (y - x)^3, О] ; 
              Manipulate[ 
             p[i_, s_] := Apply [Times, (s-st[[#]]) & /@
                Drop[Range[Length[st]], {i}]]; 
            z = Apply [Times, (st[ [#] ] - st[ [#+ 1] ]) & /@ 
                   Range [Length [st] - 1] ] ; If [z ≠ 0, 
             M = Table [1 /p[i, st[[i]]], {i, 1, Length [st] }] ; 
               G = Table[h[t, st[[i]]], {i, 1, Length[st]}]; 
             Show[If[OrderedQ[st], Plot[G.M, {t, -20, 20}], 
                Do [If [st[[i - 1]] > st[[i]], st[[i- l]] = st[[i]] , 
                      {i, 2, Length[st]}] ; Plot[G.M, {t, -20, 20}]], 
               Graphics[{Red, PointSize[Large] ,
                   Point[Table[{st[[i]], 0}, {i, 1, Length[st]}]], 
                  Text[ToString[#-1] , {st[[#]] +1.2, 0}] & /@
                     Range [ 5 ] , Axes -> True} ] ] , 
           Show[Graphics[Text["Узлы совпадают"], 
              PlotRange -> {{-25, 25} , {-20, 20}}] ] ] , 
         {{st, {-13.2, -6.0, 0.7, 5.2, 12.0}, "Узлы"}, 
          With[{r= Range[l, Length[st]]}, 
             Grid[{Spacer[3], Subscript[
                     Style["t", Italic], #-1], 
                   Slider [Dynamic@st[[#1]] , {-15, 13, .01},
                        Appearance -> "UpArrow" , ImageSize -> {200, 12} ] , 
                     Dynamic@st|[#l]l} &/@ r] ] &, 
           ControlPlacement -> Bottom} , TrackedSymbols ->{st}, 
       SaveDefinitions -> True] ]

Задача 6.1.3. Написать программу, которая бы учитывала совпадение узлов.

B-сплайны

На основе разделенных разностей мы будем строить весовые функции N_i(t) в формуле (6.2) с целью обобщения рациональных кривых Безье:

r(t)=\frac{\sum_{i=1}^nN-i(t) \omega_i p_i}{\sum_{i=1}^nN_i(t)\omega_i}, t_0 \le t \le t_m

Определение 6.1.2. Нормированным B-сплайном m-го порядка N_{i,m}(t) для неубывающей последовательности узлов t_i \le t_{i+1} \le  \dots   t_{i+m}, отсчитываемой от первого узла t_i, называется функция

N_{i,m}(t)=(t_{i+m}-t_i) \sigma_{m-1}[t_i, \dots, t_{i+m}](t)

Соответственно, ненормированным B-сплайном M_{i,m}(t) называется функция

M_{i,m}(t)=\sigma_{m-1}[t_i,\dots, t_{i+m}](t).

Определение 6.1.3. Нормированным B-сплайном m-го порядка N_{m,i}(t) для неубывающей последовательности узлов t_{i-m} \le t_{i-m+1} \le \dots \le t_{i-1} \le t_i, отсчитываемой от последнего узла t_i, называется функция

N_{m,i}(t) = (t_i -t_{i-m})\sigma_{m-1}[t_{i-m}, \dots ,t_i](t).

Соответственно определяется и ненормированный B-сплайн M_{m,i}(t) :

M_{m,i}(t) =\sigma_{m-1}[t_{i-m}, \dots ,t_i](t).

Замечание 6.1.2. Если порядок B -сплайна определять не числом узлов минус единица, а степенью усеченной функции (как многочлена t ), то введенные выше B -сплайны будут иметь (по определению) порядок не m, а (m - 1). В этом случае для них применяются другие обозначения: N_{-i}^{m-1}, N_{i-}^{m-1}, M_{i-}^{m-1}, M_{-i}^{m-1}. При этом

N_{i-}^{m-1}(t) = N_{i,m}(t),\\
N_{-i}^{m -1}(t) = N_{m,i}(t),\\
M_{i-}^{m -1}(t) = M_{i,m}(t), \\
M_{-i}^{m-1}(t) = M_{m,i}(t).

И те и другие обозначения присутствуют в литературе по B -кривым. Мы будем пользоваться первыми. В Mathematica используются вторые.

Рассмотрим (для простоты) бесконечную в обе стороны последовательность неубывающих узлов \{t_i\}, где t_i \in R, i \in Z, t_i \le t_{i+1} для любого i. Фиксируем m > 0. Тогда определены множества B -сплайнов: сплайны N_{i, m}(t) привязаны к узлу i как к первому узлу, сплайны N_{m,i}(t) привязаны к узлу i как к последнему узлу (i \in Z) .

Лемма 6.3. Если t \in [t_j,t_{j+1}], то среди функций N_{i,m}(t) и N_{m,i}(t) только m функций в каждом из этих двух классов могут быть отличны от нуля в точке t. А именно, отличны от нуля в точке t могут быть лишь следующие функции:

N_{j-m+1,m}( t ), \dots ,N_{j,m}(t),

и

N_{m,j+1}(t), \dots  , N_{m,j+m}(t).

Лемма 6.4. Для любого t \in R имеет место

\sum_i N_{i, m}(t)=\sum_iN_{m,i}(t)\equiv 1

Теорема 6.2 (формула Кокса - де Бура). Справедливы следующие формулы для ненормированных B-сплайнов при любых t, m \ge  2, \alpha \in Z и \beta = \alpha + m:

M_{\alpha, m}(t)\frac{(t_{beta}-t)M_{\alpha+1, m-1}(t)+(t-t_{\alpha})M_{\alpha, m-1}(t)}{t_{\beta}-t_{\alpha}},\\
M_{m, \beta}(t)=\frac{(t_{\beta}-t)M_{m-1, \beta}(t)+(t-t_{\alpha})M_{m-1, \beta-1}(t)}{t_{\beta}-t_{\alpha}}\\
M_{\alpha-}^{m-1}(t)=\frac{(t_{\beta}-t)M_{\alpha+1-}^{m-2}(t)+(t-t_{\alpha})M_{\alpha-}^{m-2}(t)}{t_{\beta}-t_{\alpha}}\\
M_{-\beta}^{m-1}(t)=\frac{(t_{\beta}-t)M_{-\beta}^{m-2}(t)+(t-t_{\alpha}M_{-\beta-1}^{m-2}(t)}{t_{\beta}-t_{\alpha}} ( 6.4)

Здесь ненормированные B-сплайны первого порядка равны по определению разделенным разностям функции \sigma_0(z) = (z - t)_+^0:

M_{i,1}(t)=M_{i-}^0=\begin{cases}
\frac{1}{t_{i+1}-t_i}, \qquad \mbox{если}t \in [t_i, t_{i+1}),\\
0, \qquad \mbox{иначе};
\end{cases}\\
M_{1,i}(t)=M_{-i}^0=\begin{cases}
\frac{1}{t_i-t_{i-1}}, \qquad \mbox{если } t \in [t_{i-1}, t_i), \\
0, \qquad \mbox{иначе}.
\end{cases} ( 6.5)

Теорема Кокса - де Бура позволяет вычислять B -сплайны рекуррентно с использованием формул (6.4) и (6.5).

Следствие 6.1. Пусть имеется произвольная последовательность (не обязательно неубывающих) узлов T = \{_t0, \dots ,t_m\}. Пусть среди них есть 2 неравных друг другу узла t_a и t_b: t_a \ne t_b, где 0 \le a,b \le m. Обозначим

M^T(t) =\sigma_{m-1}[T] = \sigma_{m-1}[t_0,\dots ,_tm],\\
M^{T/a}(t) = \sigma_{m-2}[T\ a] = \sigma_{m-2}[t_0,  \dots ,\hat t_a, \dots  ,t_m],\\
M^{T/b}(t) =\sigma_{m-2}[T\b] =\sigma_{m-2}[t_0, \dots ,\hat t_b, \dots ,t_m],\\
p_{ab}(t) =\frac{t_b-t}{t_b-t_a}, q_{ab}(t)=\frac{t-t_a}{t_b-t_a}, (p_{ab}+q_{ab} \evqiv 1)

где "домиком" отмечены отброшенные узлы. Тогда

M^T(t) = p_{ab}(t)M^{T\a}(t) + q_{ab}(t)M^{T\b}(t),\\
M ^{\{t_a, t_b\}} (t)=\begin{cases}
\frac{1}{|t_b-t_a|}, \qquad \mbox{если } t \in [t_a \wedge t_b, t_a \vee t_b),\\
0, \qquad \mbox{иначе},
\end{cases}

где \alpha \vee \beta = max\{\alpha, \beta \}, \alpha \wedge \beta = min\{\alpha, \beta \}.

Следствие 6.2. B - сплайны - неотрицательные функции:

M_{i,m}(t) \ge 0,	M_{i-}^{m-1}(t) \ge 0,\\
M_{m,i}(t)\ge  0,	M_{i-}^{m-1}(t) \ge 0.

Следствие 6.3. Для нормированных B-сплайнов формулы Кокса - де Бура принимают вид (\beta = \alpha + m) :

N_{\alpha,m}(t)=\frac{t_{\beta}-t}{t_{\beta}-t_{\alpha+1}}N_{\alpha+1, m-1}(t)+\frac{t-t_{\alpha}}{t_{\beta-1}-t_{\alpha}}N_{\alpha, m-1}(t),\\
N_{m, \beta}(t)=\frac{t_{\beta}-t}}{t_{\beta}-t_{\alpha+1}}N_{m-1, \beta}(t)+\frac{t-t_{\alpha}}{t_{\beta - 1}-t_{\alpha}}N_{m-1, \beta-1}(t),\\
N_{i-}^0(t)=N_{i,1}(t)=\begin{cases}
1, \qquad \mbox{если } t \in [t_i, t_{i+1})\\
0, \qquad \mbox{иначе;}
\end{cases}\\
n_{-i}^0(t)=N_{1,i}=\begin{cases}
1, \qquad \mbox{если } t \in [t_i, t_{i+1}),\\
0, \qquad \mbox{иначе}.
\end{cases}

Для сокращения объема вычислений следует сначала вычислить ненормированные B -сплайны нужного порядка по формулам Кокса - де Бура, а затем нормировать их. Если требуется вычислить все ненулевые B -сплайны порядка m для t \in [t_i,t_{i+1}] в неубывающей последовательности узлов \{t_i\}, то вычисления производятся по схеме

\begin{matrix}
&&&M_{i,1}(t)\\
& &M_{i-1, 2}(t) &M_{i,2}(t)\\
& &\vdots &\vdots\\
M_{i-m+1,m}(t) & \dots & M_{i-1}(t) & M_{i,m}(t)\\
\downarrow & \downarrow & \downarrow & \downarrow\\
N_{i-m+1,m}(t) & \dots N_{i-1,m}(t) & N_{i,m}(t)
\end{matrix}

Аналогичная схема вычислений применяется для B -сплайнов остальных трех типов.

Следствие 6.4. Для любых m \ge 2 и \alpha \in Z функции N_{\alpha,m}(t) и N_{m, \beta}(t) , где \beta = \alpha + m, построенные по неубывающей последовательности узлов \{t_i\}_{i \in Z}, являются непрерывными (m - 2) раза дифференцируемыми функциями, обращающимися в ноль вне отрезка [t_{\alpha},t_{\beta}]. На отрезке [t_i,t_{i+1}] они имеют производные до порядка (m - 1) включительно. Функции N_{\alpha, m}(t) и N_{m, \beta}(t) зависят (как от параметров) лишь от значений узлов t_{\alpha}, \dots , t_{\beta}.

Задача 6.1.4. С помощью встроенной функции в пакет Mathematica BSplineBasis[\{m,{t_0, \dots ,t_n\}\}, i, t] , вычисляющей тот из n - m нормированныx B -сплайнов N_{i, m+1}(t) порядка m + 1 (или m при втором способе определения порядка, см. выше), который привязан справа к i -му ( 0 \le i \le n - (m + 1) ) узлу из расширенного множества неубывающих узлов t_0 \le t_1 \le \dots \le t_n (см. определение ниже), наглядно изучить ненормированные и нормированные B -сплайны, привязанные к узлам справа. Обратите внимание, что в Mathematica узлы в расширенном множестве нумеруются начиная с нуля. Соответственно, в Mathematica B -сплайны в базисе нумеруются с нулевого до n - (m + 1) -го.

Замечание 6.1.3. При работе с нижеследующей программой обратите внимание, что при совпадении первых m + 1 узлов значение нулевого (самого первого) нормированного B -сплайна из базиса в нулевом (самом первом) узле становится равно 1, тогда как все остальные B -сплайны базиса обращаются в этом узле в ноль. Это значит, что когда такой базис из нормированных B -сплайнов используется для вычисления радиус-вектора B -кривой (аналогично базису Бернштейна для кривых Безье), получившаяся кривая будет начинаться в своей крайней левой опорной точке. Аналогично, при совпадении последних m + 1 узлов расширенного множества, последний сплайн базиса в последнем узле примет значение 1, а остальные будут равны в нем нулю, и, следовательно, правый конец соответствующей кривой будет находиться в ее последней опорной точке. См. ниже теорему 6.3, в формулировке которой порядок B -сплайна m соответствует значению m + 1 в обозначениях Mathematica (как уже говорилось, Mathematica использует второй способ определения порядка B -сплайна, а значит, уменьшает его на единицу по сравнению с тем способом, который используем мы).

Задача 6.1.5. Написать программу на пакете Mathematica, вычисляющую B -сплайны N_{m,i}(t) , привязанные к узлам слева.

Пример 6.1.3. Следующие две программы строят графики B -сплайнов, привязанных к узлам справа. В данном примере n = 9, то есть расширенное множество узлов состоит из 10 точек, начиная с нулевой, а m = 3, то есть порядок B -сплайна при принятом нами определении равен 4.

In[5]:=
      DynamicModule [ {m = 3, i, tt, knots} , 
         For [i = 1, i Sm + 1, i++, tt [i] = 0] ; (*m+l начальных узло равны 0*) 
          tt[5] = 4; tt[6] = 4; tt[7] = 6; tt[8] = 9; :*задали m+1 конечных узлов*) 
         Manipulate [
                knots = Join [Table [tt[i] , {i, 1, m + 1}], ss, Table [tt[j] , { j , m + 2 , 2 m + 2} ] ] ; 
                Show[ If[orderedQ[ss] , Plot [BSplineBasis [ {m, knots}, 0, t] , 
                    {t, knots[[1]] , 1.1},
                    PlotRange -> {{0, 1.1} , {0, 1.2}}, PlotLabel -> Style [N0,m+i [t] , 14] ] , 
                 Do [If [ss[[i - 1]] > ss[[1]] , ss[[i - 1]] = ss[[i]] , {i, 2, Length [ss] }] ,
              Plot[BSplineBasis[{m, knots}, 0, t], 
                   {t, knots[[1]1 , knots[[Length[knots]]] +1} ,
                      PlotRange -> + {{0, 1.1}, {0, 1. 2} }], PlotLabel -> Style [N0, m+1 [t] , 14] 
                 ]], {(ss, {0.5, 0.7}, "Узлы"}, 
                 With[(r = Range[1, Length[ss]]} , 
                    Grid[ 
                       {Spacer[3] , Subscript[Style["t", Italic] , # + m] ,
                                Slider [Dynamic@ ss[[#l]] , {0, 1, .01}, Appearance -> " UpArrow" , 
                                   ImageSize -> {200, 12}], Dynamic@ss[el]]} &/@ r] ] &,
              ControlPlacement -> Bottom} , TrackedSymbols -> {ss} , SaveDefinitions -> True 1 ]]

In|6] :=DynamicModule [{m = 3, n = 9, i, j , tt, knots, a) , 
              For [i = 1, i <= m+1, i + +, tt[i]  = 0] ;
                (*m+l  начальных  уело  равны  0*)
              For[j = 1,  j im + 1,  j++, tt[n-j]  = 7] ; 
                (*задали m+1  конечных узлов*) 
             Manipulate[knots - Join[
                    Table [tt[i] ,  {i, 1, m + 1}],  ss, 
                    Table [tt[j] ,  {j, m + 2, 2m + 2}]] ; 
                a =  (knots[[1]] +knots[[n]]) /2; 
                Show[If[OrderedQ[ss], Plot[Evaluate[
                      Table[BSplineBasis[{m, knots},  1,  t] , 
                        {1,  0, n-m-1}]],   {t, knots [[1]],  8}, 
                   PlotRange -> { {knots [ [1] ] ,  8},  {0, 1}}, 
                   Filling -> If [fill,
                       {i +1 -> {Axis,   {Opacity! -15] , Green}}} , None] , 
                  PlotLabel -> Style [Hi, m+1 [t] , 14]], 
              Do [If [ss[[i - 1]] > ss[[i]] , ss[[i - 1]] = ss[[i]] ],
                 {i, 2, Length[ss]}]; 
               Plot[Evaluate[Table[BSplineBasis[{m,  knots},  1,  t] , 
                      {1,  0, n-m-1}]],   {t, knots [[1]],  8}, 
                 PlotRange -> { {knots [ [1] ],  8},  {0, 1}}, 
                 Filling -> If [fill,
                     {i + 1 -> {Axis,   {Opacity[ -15] , Green}}} , None] , 
                 PlotLabel -> Style [Ni, т+1 [t] , 14]] ] , 
             Graphics[Arrow[{{2.5,  1.1},
         , {i + 0.1, BSplineBasis[{m, knots}, i,  i + 0.1]}}] ] ,  
     ], {{i,  3,  " Номер  полинома  i"}, 0, n-m-1,  1}, 
     Delimiter,   {{ss,   {0.5,  1.7},  "УЭлы"}, 
         With[{r=Range[1, Length[ss]]}, Grid[{Spacer[3], 
                    Subscript[Style["t",  Italic],  # + m] , 
                    Slider [Dynamic@ss[[#l]],  {0, 2,   .01},
                      Appearance -> "UpArrow" ,  ImageSize -> {200 ,  12} ] , 
                   Dynamic@ss|[#l]]} &/@r]]  &, 
         ControlPlacement -> Bottom} , 
      {{fill, True, "Заполнение"},  {True, False), 
         ControlPlacement -> Bottom} ,  SaveDefinitions -> True] ]

Светлана Петрова
Светлана Петрова
Украина
Марина Семенова
Марина Семенова
Россия, г. Чебоксары