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

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

Кривые Безье

Обычные кривые Безье

Поставим следующую задачу. Для любого набора из (n+ 1) опорных точек p_0,\dots, p_n  \in  R^3 требуется найти такие функции f_0(t), \dots , f_n(t) , не зависящие от p_0, \dots , p_n и имеющие вид полиномов по t, что кривая

r(t)=p_of_o(t)+ \dots + p_nf_n(t), t \in [0,1] ( 5.21)

обладает следующими свойствами.

  1. r(0)=p_0,r(1)=p_n.
  2. Кривая (5.21) не зависит от выбора декартовой системы координат в R^3 или, другими словами, формула (5.21) инвариантна относительно движений пространства.
  3. Если все опорные точки p_0, \dots , p_n лежат в одной плоскости, то кривая (5.21) плоская и лежит внутри выпуклой оболочки опорных точек p_0, \dots ,p_n.

Теорема 5.1. Условия 1 - 3 равносильны условиям

  • \sum_{i=0}^{n} f_i (t) = 1 для любой точки t \in [0,1] ;
  • f_i(t) \ge 0 для любого t \in  [0,1] ;
  • f_0(0) = 1, f_i (0) = 0 для любого 1 \le i \le n и f_n(1) = 1, f_i(1) = 0 для любого 0 \le i \le n-1.

Определение 5.3.1. Фиксируем целое n > 0. Базисом Бернштейна на отрезке [0,1] называется система из (n+1) полинома степени n, задаваемых формулами

B_i^n(t)=\frac{n!}{i!(n-i)!}t^i(1-t)^{n-i}=C_n^it^i(1-t)^{n-i}, 0 \le i \le n

Следующая программа рисует полиномы Бернштейна для 0 \le n \le 20 и для всех k \le  n.

Пример 5.3.1. Полиномы Бернштейна:

In[7]:=
       DynamicModule[{i, k, n, DivZ, PowerZ, Bernstein},
          DivZ[s_, 0] := 0; 
       DivZ[s_, t_] := s/ t;
          PowerZ[(x_)?((#1 ==0) &), (y_)?((#2 ==0) &)] := 1; 
       PowerZ[x_,   y_]    :=  x^y; 
         Bernstein [k_,   n_,    t_] : = Binomial [n, k]  * PowerZ [1 - t, n - k]  * PowerZ [t, k] ; 
        Manipulate [Module [ {ps , f} , If[i > n, i = n] ;
            ps = Table [ {Hue [. 67 , .6, . 6] , Opacity!. 1 (8 + 2 Boole [i == k]) ] ,
                Thickness [0.001 (1 + 4 Boole [k == i]) ] } , {k, 0 , n} ] ; 
            f[t_] := Table [Bernstein [k, n, t] , {k, 0, n}];
            Show[piot [Evaluate@f [x] , {x, 0, 1}, PlotStyle -> ps , PlotPoints -> 25 , 
               PlotRange ->  {0 , 1.1},
               Filling -> If [fill, {i + 1 ->  {Axis, {Opacity [. 15] , Green}}}, None], 
               PlotLabel -> Style [Bi,n[t] == Bernstein [i , n, t] , 14]], 
           Graphics [ If [n ==0, {} , With[{j = i + .3 Boole [i == 0] - . 3 Boole [i == n] } , 
                   Arrow[{{.5, 1.1} , {DivZ[j, n] , Bernstein[i, n, DivZ[j, n]]}}]]]] , 
           ImageSize -> {450, 300}, ImagePadding -> {{25, 25}, {25, 38}}]], 
        {{n, 12, "Степень полинома n"} , 0, 20, 1}, 
        { {i, 5 , " Номер полинома i"}, 0, n, 1}, 
        {{fill, True, "Заполнение"}, {True, False}, ControlPlacement -> Bottom}]
]

Базис Бернштейна удовлетворяет свойствам a)-c) , сформулированным в теореме, и поэтому в качестве функций f_0(t), \dots ,f_n(t) можно взять базис Бернштейна.

Определение 5.3.2. Пусть дана (n + 1) опорная точка p_0, \dots  , p_n. Тогда кривой Безье, определяемой точками p_0, \dots , p_n, называется кривая

r_B(t)=\sum_{i=1}^nB_i^n(t)p_i, t \in [0,1].

Число n называется степенью кривой Безье.

Замечание 5.3.1.

  1. Кривая Безье является полиномиальной, а следовательно, бесконечно гладкой на всей области определения параметра [0,1].
  2. Построение кривой Безье не требует сложных вычислений. Участвующие в ее определении функциональные коэффициенты (полиномы Бернштейна) зависят лишь от числа опорных точек, но не от их координат. Поэтому кривая Безье легко пересчитывается при любом изменении опорных точек. Такой пересчет требует лишь порядка n арифметических операций.
  3. Из определения кривой Безье непосредственно следует, что она проходит через свои крайние опорные точки при значениях параметра t = 0 и t = 1 соответственно. Однако через все промежуточные опорные точки кривая Безье, вообще говоря, не проходит. Таким образом, опорные точки являются лишь средствами управления кривой Безье.
  4. В своих крайних опорных точках кривая Безье касается звеньев своей опорной ломаной (ломаной, построенной по опорным точкам).

Кривые Безье в пакете Mathematica. Mathematica имеет встроенную функцию построения кривой Безье BezierCurve[{p1, p2, p3, p4}], однако эта функция строит кривую Безье только по 4 опорным точкам. Если в качестве ее аргументов задать больше, чем 4 точки, то вместо кривой Безье будет построена составная кривая Безье, имеющая изломы в каждой четвертой опорной точке (попробуйте). Для того чтобы в Mathematica построить кривую Безье по более чем 4 опорным точкам, надо пользоваться функцией BezierFunction[pts] , где [pts] - список координат опорных точек. Эта функция задает зависимость радиус-вектора кривой Безье от параметра. Кривую Безье можно изобразить, применив к ней оператор ParametricPlot или ParametricPlot3D.

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

In[8] : = DynamicModule [{pts , pts0 , n = 4} ,
                 pts0 = {{-3, 0} , {0, 4}, {2, 4} , {3, 2}} ; 
                 Manipulate[ 
                    Show [ {Graphics[{BezierCurve[pts] , Green, Line[pts] ,
                           Red, Text[ToString[#- 1] , pts [ [#]] +{0.4, 0}] & /@Range [4]}] } , 
                      PlotRange -> {{-4, 5} , {-2,5}}], {{pts , ptsO} , Locator} ] 
              ]

Следующий пример демонстрирует пункт 4 замечания.

Пример 5.3.3. Кривая Безье, построенная по пяти опорным точкам, с управляемыми второй и предпоследней точками. Цель программы - показать, что кривая Безье всегда касается звеньев своей опорной ломаной в крайних точках.

In[9]:=
        DynamicModule[{u, v, t, pts}, 
          Manipulate [pts = {{-3, 0}, и, {0, 0}, v, {3, 2}}; 
             BezierF = BezierFunction[pts] ;
             Show [ Graphics [ {RGBColor [. 12 , .34, . 65] , Line [ { {-3 , 0} , u} ] , 
               Line[{v, {3, 2}}] , AbsolutePointSize[6] , Point[{u, v} ] ,
               RGBColor[l, .21, 0] , PointSize [Large] , Point[{{-3, 0}, {0, 0}, {3, 2}}]}, 
            Axes -> True] , 
          Graphics [{Red, Text [ToString[# - 1] , pts [ [#] ] +{0.3, 0}] &/@Range[5],
              Text["Составной сплайн Эрмита 3 порядка", {7, -9}]}], 
            ParametricPlot[BezierF[t], {t, 0, 1},
              PlotStyle -> {{Red, AbsoluteThickness [2] } } ] , PlotRange -> 6, 
           ImageSize -> 6 x 72 , Background -> GrayLevel [. 98] ] , 
        {{u, {2, -3}}, {-6, -6}, {6, 6}}, {{v, {-6, -3}}, {-6, -6}, {6, 6}},  
         ControlType -> Locator] ]

Пример 5.3.4. Пример пространственной кривой Безье, построенной по 8 опорным точкам. Все точки управляемы покоординатно с помощью ползунков.

In[10]: =
       DynamicModule [ {pts , р0 , pi, р2 , рЗ , р4 , р5 , р6 , р7 , t, g} , 
         Manipulate [pts := {р0 , pi, p2 , p3 , p4 , p5 , р6 , p7} ; 
             Show[ { ParametricElot3D[g[pts] [t] , {t, 0, 1}, PlotStyle -> {Green, Thick}, 
                 Axes -> True, AxesEdge -> Automatic, AxesOrigin -> {0, 0, 0}, 
                 PlotRange -> {{-15, IS}, {-15, 15}, {-15, 15}}], 
              Graphics3D [ {Red, PointSize [Large] , Point [pts [[#]] ] &/@Range[8], 
                  Text[ToString[# - 1] , pts [ [*f] ] + {0.5, 0.5, 0.5}] & /@ Range [8] }] } ] , 
           {{p0, {0.0, 0.0, 0.0}}, {-1, -1, -1}, {1, 1, 1}}, 
           {{p1, {2.0, 1.0, 1.0}}, {1, 0, 0}, {3, 2, 2}}, 
           {{p2, {1.8, 5.2, 2.4}}, {0.8, 4.2, 1.4}, {2.8, 6.2, 3.4}}, 
           {{p3, {-2.3, 6.5, 3.0}}, {-3.3, 4.5, 2.0}, {-1.3, 7.5, 4.0}}, 
           {{p4, {-4.0, 4.0, 5.0}}, {-5.0, 3.0, 4.0}, {-3.0, 5.0, 6.0}}, 
           {{p5, {-7.0, 1.0, 6.0}}, {-8.0, 0.0, 5.0}, {-6.0, 2.0, 7.0}}, 
           {{рб, {4.8, 2.2, 8.4}}, {3.8, 1.2, 7.4}, {5.8, 3.2, 9.4}}, 
           {{p7, {9.3, 6.5, 12.0}}, {8.3, 5.5, 11.0}, {10.3, 7.5, 13.0}}, 
           ControlType -> Slider 
        ], Initialization: -> (g[pts_] : = BezierFunction [pts] ) ]

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

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