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

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

Деление кривой Безье на две кривые Безье того же порядка в отношении t* : (1 - *)

Пусть даны опорные точки p_0, \dots , p_n и кривая Безье r = r(t) , построенная по ним. Требуется для некоторого заданного t^* \in  [0,1] построить опорные точки p_0^a, \dots , p_n^a и p_0^b, \dots , p_п^b так, чтобы кривые Безье для этих новых точек совпали бы с двумя дугами исходной кривой Безье, на которые она разбивается точкой r(t*).

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

Для решения поставленной задачи введем новый параметр \tau =\frac {t}{t^*}. Имеем t = \tau t^*. Запишем формулу (5.24) в виде

r(t) = r_0(t; n) = (1 - \tau t^* + \tau t^*E)^np_0 = ( (1-\tau ) + (1-t^*+t^*E) \tau )^n p_0 ( 5.25)

Введем новый оператор сдвига E_a = (1-t^*+t^*E) и перепишем (5.25) в виде (5.24), положив p_0^a = p_0, p_i^a = E_i^a p_0^a:

r_0(t; n) = r_0^a(t; n) = ( (1 -\tau) + \tau E_a )^n p_0^a,

где \tau \in [0,1], t = \tau t^*.

Таким образом, если мы построим кривую Безье по (n + 1) точкам p_0^a, \dots ,p_n^a, определенным по формуле p_i^a = (1 - t^* + t^*E)^ip_0, эта новая кривая Безье совпадает с дугой исходной кривой Безье r(t), 0 \le t \le t^*.

Аналогично, с помощью нового параметра \xi = \frac{t-t^*}{1-t^*} и нового оператора левого сдвига L_b = (1-t^*)L+t^* (L = E^{-1}) определим (n+1) новую опорную точку p_0^b, \dots ,p_n^b по формуле p_{n_i}^b = L_b^i p_n^b, i = 0, \dots  ,n, p_n^b = p_n. Тогда дуга исходной кривой Безье на участке [t, 1] может быть задана формулой (5.23), которую можно записать в виде

r(t) = ( (1-t)L + t )^n p_n =\\
= (( 1 - (1 - t^*) \xi - t*) L+(1 -t^*) \xi+t^*)^n p_n =\\
=   ( ((1-t^*)L + t^*) (1-\xi ) + \xi )^n p_n= ( (1-\xi ) L_b +\xi )^n p_n.

Следовательно, эта дуга будет совпадать с кривой Безье, построенной по точкам p_0^b,\dots  , p_n^b.

Процедура построения точек p_0^a, \dots ,p_n^a и p_0^b, \dots ,p_n^b может быть описана более наглядно следующим образом.

  1. Исходный многоугольник с вершинами в опорных точках назовем многоугольником нулевого уровня p_0^{(0)} = p_0, \dots ,p_n^{(0)} = p_n.
  2. Строим многоугольники уровней 1,2, \dots ,n так, что вершины многоугольника следующего уровня делят стороны многоугольника предыдущего уровня в отношении t^* : (1 - t^*):
p_i^{(k)} = (1 - t^*)p_i^{(k-1)} + t^*p_{i+1}^{(k-1)}, i = 0, \dots ,n - k.

Многоугольник k -го уровня будет иметь (n-k+1) вершин: p_0^{(k)}, \dots ,p_{n-k}^{(k)} . При этом, согласно построению, сдвигая все исходные вершины вперед, мы сдвигаем вперед и все вершины многоугольника любого уровня, т. е. Ep_i^{(k)} = p_{i+1}^{(k)} . Тогда

p_i^a =p_0^{(i)}.

В самом деле, имеем по построению,

p_0^{(0)} =p_0,\\
p_0^{(1)} = (1 - t^*)p_0 + t^*p_1 = (1 - t^* + t^*E)p_0 = E_ap_0^{(0)},\\
…………………………………………….\\
p_0^{(k)} = (1 - t^*)p_0^{(k-1)} + t^*p_1^{(k-1)} = (1 - t^* + t^*E)p_0^{(k-1)} = E_ap_0^{(k-1)}, ( 5.26)

так как Ep_0^{(k-1)} = p_1^{(k-1)} . Следовательно, p_0^{(k)} = E_a^kp_0^{(0)} = E_a^kp_0 = p_k^a , где E_a = (1 - t^*) + t*E .

Аналогично строятся точки p_0^b, \dots ,p_n^b , только надо брать последовательность последних, а не первых вершин многоугольников k -го уровня.

Условия сохранения гладкости сопряжения при делении кривой Безье

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

p_n^a, \dots, p_{n-k}^a,\\
p_o^b, \dots, p_k^b. ( 5.27)

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

Увеличение числа опорных точек без изменения формы кривой Безье

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

Для кривой Безье с опорными точками p_0, \dots , p_n имеем

r(t) = r_0(t;n) = (1-t + Et)^np_0

или

r(t)=\sum_{i=0}^{n}C_n^i(1-t)^{n-i}t^ip_i

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

r(t)=(1-t+t)\sum_{i=0}^{n}C_n^i(1-t)^{n-i}t^ip_i=\\
=\sum_{i=0}^{n}C_n^i(1-t)^{n-i+1}t^ip_i+\sum_{i=0}^{n}C_n^i(1-t)^{n-i}t^{i+1}p_i=\\
=\sum_{i=0}^{n+1}C_{n+1}^i(1-t)^{n+1-i}t^i \left ( \frac{C_n^i}{C_{n+1}^i}(1 - \delta_{(n+1)i})p_i+ \frac{C_n^{i-1}}{C_{n+1}^i}(1- \delta_{0i})p_{i-1} \right ),

где \delta_{ij} - символ Кронекера-Капелли:

\delta_{ij}= \begin{cases}
1 \mbox{ при} i=j,\\
0  \mbox{ при} i \ne j
\end{cases}

Положим теперь

q_i=\frac{n+1-i}{n+1}p_i(1-\delta_{(n+1)i})+\frac{i}{n+1}p_{i-1}(1-\delta_{0i}), i=0, \dotsm n+1

Отметим, что p_{n+1} и p - 1 входят в последнее равенство с нулевыми коэффициентами, поэтому доопределять эти (не определенные пока) точки нет необходимости.

Рациональные кривые Безье

Обычные кривые Безье получаются с помощью итерирования операции деления отрезка в отношение t : (1 -t) . Так, например: p_t = (1 -t)p_0 +tp_i = (1 -t+tE)p_0 = r_0(t; 1) - кривая Безье первого порядка (здесь отрезок p_0p_l разделен в отношении t : (1 - t) ). Аналогично, r_0(t; n) = (1 - t + tE)^np_0 -кривая Безье порядка n . Здесь уже операция деления отрезка в отношении t:(1-t) проитерированаn раз.

Рациональные кривые Безье получаются таким же образом с помощью операции рационального деления отрезка с весами \omega_0 и \omega_х .

Определение 5.4.1. Рациональной кривой Безье порядка n , построенной по заданным опорным точкам p_0, \dots , p_n с заданными весами \omega_0, \dots ,\omega_n ( \omega_i > 0) , называется кривая

r_0(t;n)=\frac{(1-t+tE)^n(\omega_0p_0)}{(1-t+tE)^n\omega_0}=\frac{(1-t-tE)^n(\omega_0p_0)}{\omega_0(t;n)},

где t \in [0,1], \omega_0(t; n) = (1 -t + tE)^n\omega_0 . Здесь, как и выше, оператор E действует одновременно и на последовательности опорных точек p_0, p_1  \dots , p_n , и на последовательности весов \omega_0,\omega_1, \dots , \omega_n .

Согласно биному Ньютона, рациональная кривая Безье r_0(t;n) может быть представлена в виде

r_0(t;n)=\sum_{i=0}^nC_n^it^i(1-t)^{n-i}\frac{\omega_i}{\omega_0(t;n)}p_i

В случае равных весов \omega_0 = \dots  = \omega_n знаменатель \omega_0(t; n) превращается в постоянную, а рациональная кривая Безье - в обычную кривую Безье.

Замечание 5.4.1.

  1. Так же как и обычная кривая Безье, рациональная кривая Безье всегда находится в выпуклой оболочке своих опорных точек, проходит через первую и последнюю опорные точки и, вообще говоря, не проходит через промежуточные опорные точки.
  2. Так же как и для обычной кривой Безье, в своих крайних опорных точках рациональная кривая Безье касается звеньев своей опорной ломаной (ломаной, построенной по опорным точкам).
  3. Так же как и для обычной кривой Безье, i -тая производная на конце рациональной кривой Безье определяется (i + 1) крайней опорной точкой, а также весами этих точек.
  4. В отличие от обычных кривых Безье, рациональные кривые Безье способны точно (а не приблизительно) представлять дуги кривых второго порядка. Это очень важно для ряда инженерных приложений, в которых требуется, чтобы та или иная кривая в точности являлась дугой, скажем, эллипса, параболы или гиперболы (поскольку от этого зависят физические свойства той детали, в описании которой участвует данная кривая).
  5. По сравнению с обычной кривой Безье рациональная кривая Безье обладает более мощными средствами управления. Ее управляющими параметрами являются теперь уже не только опорные точки, но и их веса. Веса являются принципиально новым множеством управляющих параметров по сравнению с опорными точками, поскольку изменение весов и изменение опорных точек действует на рациональную кривую Безье по-разному.
  6. При смещении опорной точки p_i на вектор \xi_i все точки рациональной кривой Безье смещаются в направлении вектора \xi_i (на разные величины). Поскольку обычная кривая Безье является частным случаем рациональной кривой Безье (в случае равенства весов), то же верно и для обычной кривой Безье.
  7. При увеличении веса \omega_i опорной точки pi все точки рациональной кривой Безье испытывают смещение в направлении опорной точки pi (на разные величины). Это смещение может оказаться нулевым (например, концы кривой не смещаются при изменении весов), но вектор смещения всегда направлен от исходного положения точки кривой к опорной точке p_i , если вес этой опорной точки увеличивается, и в противоположную сторону, если он уменьшается.

Рациональные кривые Безье в пакете Mathematica. Mathematica не имеет встроенной поддержки рациональных кривых Безье. В частности, функция BezierFunction[pts] не работает, если в качестве ее аргумента взять последовательность вещественных чисел (весов), а не координат точек пространства размерности 2 или больше. Поэтому при вычислении знаменателя формулы радиус-вектора рациональной кривой Безье с помощью Mathematica следует дополнить список весов еще одной координатой до двумерных векторов, а затем использовать лишь первую компоненту получившейся двумерной вектор-функции.

Пример 5.4.1. Рациональная кривая Безье, построенная по восьми опорным точкам и их весам, с возможностью непосредственного управления опорными точками с помощью мыши, а весами - с помощью ползунков, расположенных слева от графика. Для сравнения на том же графике изображена также и обычная кривая Безье, построенная по тем же самым опорным точкам, но без использования весов. Первоначально все веса сделаны одинаковыми, поэтому после запуска программы обе кривые совпадают. При изменении весов они будут расходиться:

In[13]: =
           DynamicModule [ {pts0 , w0, wl, w2, w3; w4 , w5 , w6, w7 , ww, n} , 
              Pts0 = {{-10.0, 0.0}, {-3.0, 7.0}, {1.1, -7.2}, {4.3, -8.5},
                   {-16.0, 12.0}, {-2.1, 1.7}, {-8.2, 1.4}, {12.2, 5.4}}; 
                n = Length [pts0] ; 
                Manipulate[ 
                ww = {w0 , wl, w2 , w3 , w4 , w5 , w6 , w7 } ; 
                 Show[ 
                   {Graphics [{Red, Text [ToString [# - 1] , pts [ [#] ] +{1.2, 0.2}] &/@Range[n], 
                      Text[ 
                          "Рациональная кривая Безье с весами \omega^i в сравнении с 
                               обычной кривой 
                              Безье", {-7.2, 13}]}], 
                        ParametricPlot[{fBez [pts, ww] [t] / fwBez [ww] [t] [ [1] ] , f0Bez [pts] [t] } , 
                              {t, 0, 1}] 
                          } , Axes -> True, PlotRange -> {{-30, 15} , {-10, 15}}] , 
                        {{pts, pts0}, Locator},
                        {{w0, 1}, 1, 100}, {{wl, 1}, 1, 100}, {{w2, 1}, 1, 100},
                        {{w3, 1}, 1, 100}, {{w4, 1}, 1, 100}, {{w5, 1}, 1, 100}, {{w6, 1}, 1, 100}, 
                        {{w7, 1} , 1, 100} , 
                        Initialization : -> (
                               f0Bez [J>LS_] : = BezierFunction [pts] ;
                               fwBez [ww_]   := BezierFunction[Table [{w[ [i] ] , 1}, {i, 1, n} ] ] ;
                               fBez [pts_f ww_]   : = BezierFunction [pts ww] ; )]]

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