Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ИГС / Lab_03 / labor_03b.doc
Скачиваний:
9
Добавлен:
17.04.2018
Размер:
330.75 Кб
Скачать

Сплайновые поверхности.

Сплайновые поверхности, как и сплайновые кривые, строятся по заданным опорным векторам. Для сплайновых поверхностей опорные векторы будем нумеровать двумя индексами:

(71)

Сплайновые поверхности в этом случае, в параметрической форме, имеют следующий вид:

(72)

В качестве функций ai(u),bj(v) обычно берутся сплайновые функции рассмотренные выше. Форма записи (72) называется тензорным произведением.

Запишем уравнение (72) в следующем виде:

(73)

Из уравнений (73) видно, что векторные функции – это сплайновые кривые в параметрическом виде, а сплайновая поверхность– это суперпозиция таких сплайновых кривых.

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

Бикубическая поверхность Безье.

Создадим бикубическую элементарную поверхность Безье. В качестве опорных векторов возьмем 16 опорных векторов, которые оформим в виде следующей матрицы опорных векторов:

(74)

В качестве функций ai(u),bj(v) в формуле (72) возьмем кубические сплайновые функции Безье (30)b3,i(t).

Сплайновая бикубическая элементарная поверхность Безье будет иметь следующий вид:

(75)

Уравнение элементарной поверхности Безье (75) можно переписать в матричном виде. Введем два столбца, элементами которых являются разные степени параметров u,v:

(76)

Теперь, если взять матрицу Безье (34) Mb, то уравнение (75) можно записать в следующем виде:

(77)

Создадим программу gr3D02.cppкоторая строит элементарную поверхность Безье. Возьмем за основу программуgr3D01.cppи переделаем ее.

Введем 16 опорных векторов.

//координаты 16-ти опорных векторов

//для элементарной поверхности Безье

POINT3 Pe[4][4];

Расположим эти 16 опорных точек на элементе сферической поверхности.

//располагаем 16 точек на элементе сферической поверхности

double phi, tet, dphi, dtet;

double phib, phie, tetb, tete;

int Nphi=4, Ntet = 4;

phib = 0; phie = 90; tetb = 15; tete = 75;

dphi = (phie - phib)/(Nphi-1); dtet = (tete - tetb)/(Ntet-1);

//задаем значения основных опорных точек в мировой системе координат

for(int n = 0; n < Nphi; n++)

{

phi = phib + dphi*n;

for(int m = 0; m < Ntet; m++)

{

tet = tetb + dtet*m;

Ve[n][m].x = 3*sin(3.14159/180*tet)*cos(3.14159/180*phi);

Ve[n][m].y = 3*sin(3.14159/180*tet)*sin(3.14159/180*phi);

Ve[n][m].z = 3*cos(3.14159/180*tet);

}

Создаем функцию, вычисляющую 4 кубические функции Безье.

//четыре функции Безье

double Bezier(int i, double t)

{

double b;

switch(i)

{

case 0 : b=(1-t)*(1-t)*(1-t); break;

case 1 : b=3*t*(1-t)*(1-t); break;

case 2 : b=3*t*t*(1-t); break;

case 3 : b=t*t*t; break;

}

return b;

}

Создаем функцию, вычисляющую элементарную поверхность Безье по формуле (75).

//элементарная поверхность Безье

POINT3 BezierSurf(double u, double v)

{

POINT3 Bz;

double Bzu[4], Bzv[4];

for(int n=0; n<4; n++)

{

Bzu[n] = Bezier(n,u); Bzv[n] = Bezier(n,v);

}

Bz.x = 0; Bz.y = 0; Bz.z = 0;

for(int i=0; i<4; i++)

for(int j=0; j<4; j++)

{

Bz.x += Bzu[i]*Bzv[j]*Ve[i][j].x;

Bz.y += Bzu[i]*Bzv[j]*Ve[i][j].y;

Bz.z += Bzu[i]*Bzv[j]*Ve[i][j].z;

}

return Bz;

}

Рисуем полигональную сетку оп опорным точкам, с помощью следующего кода.

//рисуем полигональную сетку с помощью линий белого цвета

HPEN hPen = CreatePen(PS_SOLID,1,RGB(255,255,255));

HPEN hPenOld = (HPEN)SelectObject(hdc,hPen);

double xe, ye;

int x1, y1, x2, y2;

//горизонтальные линии

for(int m = 0; m <4; m++)

{

xe = Xe(Ve[0][m].x,Ve[0][m].y);

ye = Ye(Ve[0][m].x,Ve[0][m].y,Ve[0][m].z);

x1=xn(xe);

y1=ym(ye);

for(int k=1; k<4; k++)

{

xe = Xe(Ve[k][m].x,Ve[k][m].y);

ye = Ye(Ve[k][m].x,Ve[k][m].y,Ve[k][m].z);

x2 = xn(xe);

y2 = ym(ye);

MoveToEx(hdc,x1,y1,0);

LineTo(hdc,x2,y2);

x1 = x2; y1 = y2;

}

}

//вертикальные линии

for(int k = 0; k <4; k++)

{

xe = Xe(Ve[k][0].x,Ve[k][0].y);

ye = Ye(Ve[k][0].x,Ve[k][0].y,Ve[k][0].z);

x1=xn(xe);

y1=ym(ye);

for(int m=1; m<4; m++)

{

xe = Xe(Ve[k][m].x,Ve[k][m].y);

ye = Ye(Ve[k][m].x,Ve[k][m].y,Ve[k][m].z);

x2 = xn(xe);

y2 = ym(ye);

MoveToEx(hdc,x1,y1,0);

LineTo(hdc,x2,y2);

x1 = x2; y1 = y2;

}

}

Рисуем элементарную поверхность Безье в виде «горизонтальных» и «вертикальных» линий с помощью следующего кода.

//рисуем сплайновую поверхность Безье с помощью линий

HPEN hPen1 = CreatePen(PS_SOLID,1,RGB(255,255,0));

HPEN hPenOld = (HPEN)SelectObject(hdc,hPen1);

double xt,yt,zt,xe,ye;

int x1, y1, x2, y2;

//"горизонтальные линии"

//число горизонтальных линий

int Nsp = 2;

int Ns = 10;

double v, u, du = 1.0/(Ns-1), dv = 1.0/(Nsp-1);

for (int i=0; i<Nsp; i++)

{

v = dv*i;

u = 0;

xt = BezierSurf(u,v).x;

yt = BezierSurf(u,v).y;

zt = BezierSurf(u,v).z;

xe = Xe(xt,yt);

ye = Ye(xt,yt,zt);

x1 = xn(xe);

y1 = ym(ye);

MoveToEx(hdc,x1,y1,0);

for(int j=1; j<Ns; j++)

{

u = du*j;

xt = BezierSurf(u,v).x;

yt = BezierSurf(u,v).y;

zt = BezierSurf(u,v).z;

xe = Xe(xt,yt);

ye = Ye(xt,yt,zt);

x1 = xn(xe);

y1 = ym(ye);

LineTo(hdc,x1,y1);

}

}

//"вертикальные линии"

//число вертикальных линий

int Msp = 2;

int Ms = 10;

dv = 1.0/(Ms-1); du = 1.0/(Msp-1);

for ( i=0; i<Msp; i++)

{

u = du*i;

v = 0;

xt = BezierSurf(u,v).x;

yt = BezierSurf(u,v).y;

zt = BezierSurf(u,v).z;

xe = Xe(xt,yt);

ye = Ye(xt,yt,zt);

x1 = xn(xe);

y1 = ym(ye);

MoveToEx(hdc,x1,y1,0);

for(int j=1; j<Ms; j++)

{

v = dv*j;

xt = BezierSurf(u,v).x;

yt = BezierSurf(u,v).y;

zt = BezierSurf(u,v).z;

xe = Xe(xt,yt);

ye = Ye(xt,yt,zt);

x1 = xn(xe);

y1 = ym(ye);

LineTo(hdc,x1,y1);

}

}

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

//Текстура, число точек в рисунке текстуры

const int Ntext = 100;

//координаты текстуры

double ut[Ntext], vt[Ntext];

Узор текстуры создадим в виде цветка.

//Задается массив для рисунка текстуры

double ro, t, dt = 6.28/(Ntext-1);

for(int i=0; i<Ntext; i++)

{

t = dt*i;

ro = 0.5*cos(4.*t)*cos(4.*t);

ut[i] = ro*cos(t)+0.5;

vt[i] = ro*sin(t)+0.5;

}

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

//рисуем узор текстуры

HPEN hPen3 = CreatePen(PS_SOLID,2,RGB(0,100,255));

SelectObject(hdc,hPen3);

xt = BezierSurf(ut[0],vt[0]).x;

yt = BezierSurf(ut[0],vt[0]).y;

zt = BezierSurf(ut[0],vt[0]).z;

xe = Xe(xt,yt);

ye = Ye(xt,yt,zt);

x1 = xn(xe);

y1 = ym(ye);

MoveToEx(hdc,x1,y1,0);

for(int k=1; k<Ntext; k++)

{

xt = BezierSurf(ut[k],vt[k]).x;

yt = BezierSurf(ut[k],vt[k]).y;

zt = BezierSurf(ut[k],vt[k]).z;

xe = Xe(xt,yt);

ye = Ye(xt,yt,zt);

x1 = xn(xe);

y1 = ym(ye);

LineTo(hdc,x1,y1);

}

На Рис.35 изображена элементарная бикубическая поверхность Безье, построенная по формулам (75).

Рис.35

Элементарная бикубическая поверхность Безье. Узор текстуры взят в виде цветка.

Рис.36

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

(Изображение на Рис. 35 создано программой gr3D02.cpp.)

(Изображение на Рис. 36 создано программой gr3D03.cpp.)

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

Составную поверхность Безье можно построить из отдельных элементарных поверхностей Безье. В литературе по компьютерной графике элементарные сплайновые поверхности иногда называют кусками поверхности или порциями поверхности (surfacepatches), а составную сплайновую поверхность называют просто сплайновой поверхностью.

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

Будем предполагать, что составная поверхность похожа на деформированный платок с четырьмя углами. Тогда можно говорить, что в вертикальном направлении на платке располагается Neэлементарных поверхностей, а в горизонтальном направлении располагаетсяMeэлементарных поверхностей. Другими словами можно сказать, что составная поверхность содержитNeMeэлементарных поверхностей.

Итак, пусть составная поверхность содержит NeMeэлементарных поверхностей, тогда число опорных векторов будет равноNM, где.

(78)

Опорные векторы в этом случае можно объединить в векторную матрицу размерностью NM.

(79)

Алгоритм построения создания составной поверхности будет следующим. В матрице (79) в левом верхнем углу выбираем первые 16 опорных векторов, в виде матрицы 44.

(80)

Рассматривая опорные векторы (80) как опорные векторы в формуле (75) строим первую элементарную поверхность Безье. Затем перемещаемся по матрице (79) вправо на 4 столбика, выбираем следующие 16 опорных векторов, в виде матрицы.

(81)

Рассматривая опорные векторы (81) как опорные векторы в формуле (75) строим вторую элементарную поверхность Безье. Таким образом, двигаемся вправо по матрице (79) пока не дойдем до последних 16 опорных векторов, которые можно представить в виде матрицы 44.

(82)

Рассматривая опорные векторы (82) как опорные векторы в формуле (75) строим Ne–тую элементарную поверхность Безье. После этого опускаемся в матрице (79) на 4 строчки вниз и все повторяется сначала. В результате будут построены всеNeMeэлементарные поверхности.

На Рис.36 изображена составная бикубическая поверхность Безье. В этом примере число элементарных поверхностей Безье равно следующему значению:

Число опорных векторов рано соответственно следующему значению:

На Рис.36 каждая элементарная поверхность Безье и текстура на ней изображены своим цветом. Прямые линии полигональной сетки изображены белым цветом. 70 опорных точек были помещены на поверхность сферы.

На Рис.37 изображена замкнутая составная бикубическая поверхность Безье.

Рис.37

Замкнутая составная бикубическая поверхность Безье, составленная из 12-и элементарных поверхностей Безье.

Рис.38

Элементарная бикубическая B-сплайновая поверхность, построенная по 16 опорным точкам. Узор текстуры взят в виде цветка.

(Изображение на Рис. 37 создано программой gr3D03.cpp.)

(Изображение на Рис. 38 создано программой gr3D04.cpp.)

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

, (83)

то составная сплайновая поверхность Безье замкнется по границам, соответствующим этим опорным векторам.

На Рис.37 изображена замкнутая составная бикубическая поверхность Безье. В этом примере число элементарных поверхностей Безье равно 12.

Соседние файлы в папке Lab_03