14576

Кривые и поверхности в OpenGL

Лабораторная работа

Информатика, кибернетика и программирование

Лабораторная работа № 7 Кривые и поверхности в OpenGL Кривые Безье Кривая Безье задается векторной функцией одной переменной Cu = [ Xu Yu Zu] Где u изменяется в некоторой области например [0.0 1.0]. Фрагмент поверхности Безье задается векторной фу

Русский

2013-06-08

75 KB

49 чел.

Лабораторная работа № 7

Кривые и поверхности в OpenGL

Кривые Безье

Кривая Безье задается векторной функцией одной переменной

   C(u) = [ X(u), Y(u), Z(u)],

     

Где  u изменяется в некоторой области, например, [0.0, 1.0].

Фрагмент поверхности Безье задается векторной функцией двух переменных

   S(u, v) = [ X(u, v), Y(u, v), Z(u, v) ].

Для каждого значения u и v формула C( ) или S( ) вычисляет точку на кривой ( поверхности ). При использовании Безье-вычисления сначала выбирают функцию C( ) или S( ), включают ее (Безье-вычислитель), а затем используют команду glEvalCoord1( ) или glEvalCoord2( ) вместо команды glVertex*( ). В этом случае вершина кривой или поверхности может использоваться точно также, как и любая другая вершина, например, для формирования точки или линии. Кроме того, другие команды автоматически генерируют серии вершин, образующих пространство регулярной однородной сетки по оси u (или по осям u и v ).  

Если  представляет набор контрольных точек, то уравнение

   C(u) =   - представляет собой кривую Безье при изменении u от 0.0 до 1.0, где

 

- многочлен Бернштейна степени n, который задается следующим уравнением

    

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

Функция обработки полинома одной переменной настраивается в процессе инициализации OpenGL- программы посредством вызова функции

 glMap1f(type, u_min, u_max, stride, order, point array)

 Аргумент  type задает тип объекта, который будет представлен полиномом Безье. Можно назначить в качестве значения этого аргумента константы, задающие трех- и четырехмерные геометрические точки, цвет в формате RGBA, нормали, индексированные цвета и координаты текстур ( от одно- до четырехмерных).

Table 12-1 : Types of Control Points for glMap1*()

Parameter

Meaning

GL_MAP1_VERTEX_3

x, y, z vertex coordinates

GL_MAP1_VERTEX_4

x, y, z, w vertex coordinates

GL_MAP1_INDEX

color index

GL_MAP1_COLOR_4

R, G, B, A

GL_MAP1_NORMAL

normal coordinates

GL_MAP1_TEXTURE_COORD_1

s texture coordinates

GL_MAP1_TEXTURE_COORD_2

s, t texture coordinates

GL_MAP1_TEXTURE_COORD_3

s, t, r texture coordinates

GL_MAP1_TEXTURE_COORD_4

s, t, r, q texture coordinates

 Указатель на массив опорных точек полинома передается функции через аргумент point_array. Аргументы u_min, u_max определяют область существования параметра полинома. Аргумент stride представляет собой количество значений параметра между сегментами кривой. Значение аргумента order должно быть равно количеству опорных точек. Для формирования кубической трехмерной кривой в форме В-сплайна, определенной на интервале (0,1), функции glMap1f() следует передать такой набор аргументов:

point data[]= {…};

glMap1f(GL_MAP_VERTEX_3, 0.0, 1.0, 3, 4, data);

 После настройки функция активизируется посредством вызова:

 glEnable(type);

 Если функция расчета активизирована, то можно получить от нее значения полинома, вызвав функцию:

 glEvalCoord1f(u);

 Таким образом, обращение к glEvalCoord1f() может заменить обращение к функциям glVertex(), glColor(), glNormal(). Пусть, например, функция расчета настроена на формирование кривой Безье на интервале (0,10) по некоторому массиву опорных точек. Набор из 100 точек кривой, равноотстоящих на этом интервале можно получить с помощью такого фрагмента программы:

 glBegin(GL_LINE_STRIP)

 for(i=0; i<100; i++) glEvalCoord1f( (float)i/100.);

glEnd();  

 Если значения параметра u распределены равномерно, то для вычисления точек на кривой следует использовать функции glMapGrid1f() и glEvalMesh1(), например:

 glMapGrid1f(100, 0.0, 10.0);

glEvalMesh1(GL_LINE, 0, 100);

 После вызова glMapGrid1f() устанавливается равномерная сетка в 100 отсчетов, а после вызова функции glEvalMesh1() будет сформирована кривая.

Пример программы вычисления и рисования полинома Безье.

#include <GL/glut.h>

#include <stdlib.h>

GLfloat ctrlpoints[4][3] = {

{ -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0},

{2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}};

void init(void)

{

  glClearColor(0.0, 0.0, 0.0, 0.0);

  glShadeModel(GL_FLAT);

  glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);

  glEnable(GL_MAP1_VERTEX_3);

}

void display(void)

{

  int i;

  glClear(GL_COLOR_BUFFER_BIT);

  glColor3f(1.0, 1.0, 1.0);

  glBegin(GL_LINE_STRIP);

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

        glEvalCoord1f((GLfloat) i/30.0);

  glEnd();

  /* The following code displays the control points as dots. */

  glPointSize(5.0);

  glColor3f(1.0, 1.0, 0.0);

  glBegin(GL_POINTS);

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

        glVertex3fv(&ctrlpoints[i][0]);

  glEnd();

  glFlush();

}

void reshape(int w, int h)

{

  glViewport(0, 0, (GLsizei) w, (GLsizei) h);

  glMatrixMode(GL_PROJECTION);

  glLoadIdentity();

  if (w <= h)

     glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,

              5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);

  else

     glOrtho(-5.0*(GLfloat)w/(GLfloat)h,

              5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);

  glMatrixMode(GL_MODELVIEW);

  glLoadIdentity();

}

void keyboard(unsigned char key, int x, int y)

{

  switch (key) {

     case 27:

        exit(0);

        break;

  }

}

int main(int argc, char** argv)

{

  glutInit(&argc, argv);

  glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);

  glutInitWindowSize (500, 500);

  glutInitWindowPosition (100, 100);

  glutCreateWindow (argv[0]);

  init ();

  glutDisplayFunc(display);

  glutReshapeFunc(reshape);

  glutKeyboardFunc (keyboard);

  glutMainLoop();

  return 0;

}

Поверхности Безье

Математически  фрагмент  поверхности  Безье  задается  уравнением                                                                                                   S(u,v)=

где - представляет собой множество  контрольных точек, а функции - те же самые многочлены Бернштейна, что и для одного измерения. Значения  могут представлять вершины, нормали, цвета или текстурные координаты.

Поверхности Безье формируются в OpenGL примерно по той же методике, что и кривые, только роль функции инициализации играет не glMap1*(), а glMap2*(), а для считывания результатов следует обращаться к функции glEvalCoord2*() вместо glEvalCoord1*(). В обеих функциях нужно специфицировать данные, относящиеся к двум независимым параметрам u и v. Например, функция glMap2f() имеет такой формат вызова:

glMap2f(type, u_min, u_max, u_stride, u_order, v_min, v_max, v_stride, v_order, point_array);

 Настройка функции вычисления на работу с бикубической поверхностью Безье, определенной на области (0,1)х(0,1), выполняется таким вызовом glMap2f():

glMap2f(GL_MAP_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4, data);

 Для обоих независимых переменных нужно задать порядок полинома (аргументы u_order и v_order) и количество значений параметра между сегментами (аргументы u_stride и v_stride), что обеспечивает дополнительную гибкость при формировании поверхности. Обратите внимание на то, что значение v_stride для второго параметра равно 12, поскольку в массиве опорных точек  data данные хранятся по строкам. Поэтому для перехода к следующему элементу этой же строки нужно «перешагнуть» три числа в формате float, а для перехода к следующему элементу в этом же столбце нужно «перешагнуть» через 3*4=12 чисел в формате float. Способ вызова программы расчета зависит от того, какой результат мы хотим получить,- вывести на экран сеть или сформировать многоугольники для последующего раскрашивания. Если ставится задача сформировать на экране сеть, то соответствующий фрагмент программы должен выглядеть примерно так:

 for(j=0; j<100; j++)

{

glBegin(GL_LINE_STRIP);

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

 glEvalCoord2f((float)i/100.0, (float)j/100.0);

glEnd();

  glBegin(GL_LINE_STRIP);

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

 glEvalCoord2f((float)j/100.0, (float)i/100.0);

glEnd();

}

 Если же желательно сформировать множество многоугольников, то фрагмент должен выглядеть так:

 for(j=0; j<99; j++)

{

 glBegin(GL_QUAD_STRIP)

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

 {

 glEvalCoord2f( (float)i/100.0, (float)j/100.0);

 glEvalCoord2f( (float)(i+1)/100.0, (float)j/100.0);

 }

 glEnd();

}

Для работы на равномерной сетке следует использовать функции glMapGrid2*() и glEvalMesh2(). Тогда в самое начало программы, в ту часть, которая отвечает за инициализацию, нужно включить такой фрагмент:

 glMapGrid2f(100, 0.0, 1.0, 100, 0.0, 1.0);

 В функции отображения display() нужно вызвать glEvalMesh2():

glEvalMesh2(GL_FILL, 0, 100, 0, 100);

 Для работы алгоритмов тонирования (закрашивания) сформированной поверхности при настройке режима учета освещения нужно дополнительно вызвать функцию glEnable(), передав ей в качестве аргумента константу GL_AUTO_NORMAL:

glEnable(GL_AUTO_NORMAL);

 Это позволит OpenGL автоматически вычислять вектор нормали к каждому участку формируемой поверхности и использовать этот вектор при закрашивании участков этой поверхности.

Пример программы аппроксимации с помощью поверхности Безье функции z=sin(x+y):

#include <stdlib.h>

#include <GL/glut.h>

#include <math.h>

#include <stdio.h>

GLfloat ctrlpoints[6][6][3];

void initlights(void)

{

  GLfloat ambient[] = {1.0, 1.0, 1.0, 1.0};

  GLfloat position[] = {0.0, 0.0, 2.0, 1.0};

  GLfloat mat_diffuse[] = {1.0, 1.0, 1.0, 1.0};

  GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};

  GLfloat mat_shininess[] = {50.0};

  glEnable(GL_LIGHTING);

  glEnable(GL_LIGHT0);

  glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);

  glLightfv(GL_LIGHT0, GL_POSITION, position);

  glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);

  glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

  glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

}

void display(void)

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glPushMatrix();

  glRotatef(85.0, 1.0, 0.0, 0.0);

glEvalMesh2(GL_FILL, 0, 10, 0, 10);

  glPopMatrix();

  glFlush();

}

void init(void)

{

float x,y;

int i,j;

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

{

x=3.1415/5.0*(float)i;

for(j=0; j<6; j++)

{

 y=3.1415/5.0*(float)j;

 ctrlpoints[i][j][0]=x;

 ctrlpoints[i][j][1]=y;

 ctrlpoints[i][j][2]=sin(x+y);

}

}

  glClearColor(0.0, 0.0, 0.0, 0.0);

  glEnable(GL_DEPTH_TEST);

  glMap2f(GL_MAP2_VERTEX_3, 0, 4, 3, 4,

          0, 4, 18, 4, &ctrlpoints[0][0][0]);

  glEnable(GL_MAP2_VERTEX_3);

  glEnable(GL_AUTO_NORMAL);

 glMapGrid2f(10, 0.0, 4.0, 10, 0.0, 4.0);

  initlights();       /* for lighted version only */

}

void reshape(int w, int h)

{

  glViewport(0, 0, 400, 400);

  glMatrixMode(GL_PROJECTION);

  glLoadIdentity();

        glOrtho(-1.0,2.0, -1.0, 2.0, -2.0, 2.0);

  glMatrixMode(GL_MODELVIEW);

  glLoadIdentity();

}

void keyboard(unsigned char key, int x, int y)

{

  switch (key) {

     case 27:

        exit(0);

        break;

  }

}

int main(int argc, char **argv)

{

  glutInit(&argc, argv);

  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);

  glutInitWindowSize (500, 500);

  glutInitWindowPosition (100, 100);

  glutCreateWindow(argv[0]);

  init();

  glutReshapeFunc(reshape);

  glutDisplayFunc(display);

  glutKeyboardFunc(keyboard);

  glutMainLoop();

  return 0;

}


 

А также другие работы, которые могут Вас заинтересовать

83137. Відтворення культурної спадщини українського народу 510.5 KB
  Мета: дати учням уявлення про давні зимові обряди; ознайомити з святами: святого Миколая, Маланки та Василя, Різдва Христового, Водохреща (Йордан); зацікавити учнів народними звичаями, традиціями; збагатити духовний світ дітей; розвивати відчуття святкової піднесеності мовлення...
83138. Інформація. Інформаційні процеси: отримання, зберігання, опрацювання і передавання повідомлень 139.5 KB
  Мета: ознайомити учнів з поняттям інформація з інформаційними процесами: отримання зберігання опрацювання і передавання інформації; розвивати спостережливість пам’ять мову; навички роботи з мишею; виховувати наполегливість у досягненні мети працелюбність інтерес до вивчення інформатики.
83139. Населення Землі. Культура зовнішності людини. Її стиль 166 KB
  Сформувати уявлення про населення Землі про основні раси людей на різних материках; ознайомити дітей із різними стилями зовнішності людини; розвивати вміння визначати стильову єдність одягууважність пізнавальний інтерес; виробляти уміння узагальнювати робити висновки оцінювати результати діяльності...
83140. Создание женского образа «Снежной королевы» с использованием различных элементов прически 4.04 MB
  Актуальностью для данной работы является постоянный интерес парикмахеров и технологов по прическам из длинных волос к разным историческим эпохам, для которых характерно разнообразие элементов причесок, методов и способов их выполнения.
83141. Курсовое проектирование по теории вероятностей, математической статистике и случайным процессам с элементами научно-исследовательской работы студентов 4.56 MB
  Задачи курсового проектирования по конкретной дисциплине, естественно, определяются ее спецификой, однако можно выделить и общие вопросы, не зависящие от предметной области, в том числе такие, как: профессиональная ориентация студента в изучаемых в университете направлениях (на 1 курсе, когда студент выбирает для себя направление бакалавриата)...
83142. Экологическая политика и международная деятельность Республики Беларусь в области охраны окружающей среды 968.49 KB
  Экологическая ситуация в Республике Беларусь имеет региональный характер. Региональная специфика экологических проблем определяется взаимодействием нескольких основных факторов. К их числу относятся, во-первых, неоднородность природных условий территории, а, следовательно, и неодинаковая устойчивость ее различных частей к внешним воздействиям.
83143. Учебное пособие по дисциплине: Металлические конструкции 9.04 MB
  Строительство является одной из самых металлоемких отраслей народного хозяйства. Значительная часть стали расходуется на изготовление металлоконструкций, из которых возводятся автодорожные и железнодорожные мосты, каркасы промышленных и гражданских зданий, башни и мачты антенных устройств, опоры линий электропередачи...
83145. ВИКОРИСТАННЯ ДИДАКТИЧНИХ ІГОР НА УРОКАХ ОБРАЗОТВОРЧОГО МИСТЕЦТВА В СЕРЕДНІХ КЛАСАХ 218 KB
  Проблеми перебудови нашого суспільства нерозривно пов’язані з вирішенням завдань формування творчої особистості. Адже саме така особистість є справжнім творцем історії, оскільки весь шлях, який пройдено людством, – це безперервний процес творіння.