Post on 14-Jan-2016
description
Superfícies de Bézier
Visualização 3DEstruturas de Dados Básica (Global) para Construção de uma Superfície Bézier 3D:
// Pontos de controle da Bézier (Ver teoria da Sala de Aula)
GLfloat pontos[4][4][3] = {
{{0.0, 0.0, 0.0}, {0.3, 0.5, 0.0}, {0.7, 0.5, 0.0}, {1.0, 0.0, 0.0}},
{{0.0, 0.0, 0.3}, {0.3, 0.5, 0.3}, {0.7, 0.5, 0.3}, {1.0, 0.0, 0.3}},
{{0.0, 0.0, 0.7}, {0.3, 0.5, 0.7}, {0.7, 0.5, 0.7}, {1.0, 0.0, 0.7}},
{{0.0, 0.0, 1.0}, {0.3, 0.5, 1.0}, {0.7, 0.5, 1.0}, {1.0, 0.0, 1.0}}
};
#define SENS_ROT 5.0#define SENS_OBS 15.0#define SENS_TRANSL 30.0
Superfícies de Bézier
Para Construir a Superfície de Bézier são necessários principalmente: uma estrutura de Dados (slide anterior) e as funções a seguir:
// Função para calcular a Superfície (Chamada de dentro da inicializa)
// Define significado dos pontos de controle
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &pontos[0][0][0]);
// Ativa geração de coordenadas
glEnable(GL_MAP2_VERTEX_3);
Superfícies de Bézier
Explicação mais Detalhada// Função para calcular a superfície (Chamada de dentro da inicializa)
// Define significado dos pontos de controle
glMap2f(GL_MAP2_VERTEX_3,GLfloat u1, GLfloat u2, GLint ustride,
GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat *pontos);
•GL_MAP2_VERTEX_3: significado dos pontos de controle. Outras opções podem ser: GL_MAP2_VERTEX_4, GL_MAP2_INDEX, GL_MAP2_COLOR_4, GL_MAP2_NORMAL, GL_MAP2_TEXTURE_COORD_1, GL_MAP2_TEXTURE_COORD_2, GL_MAP2_TEXTURE_COORD_3 e GL_MAP2_TEXTURE_COORD_4.
• u1 e u2, v1 e v2 definem os intervalos para as variáveis de controle em duas dimensões.
Superfícies de Bézzier
Explicação mais Detalhada// Função para calcular a Bézier (Chamada de dentro da inicializa)
// Define significado dos pontos de controle
glMap2f(GL_MAP2_VERTEX_3,GLfloat u1, GLfloat u2, GLint ustride,
GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat *pontos);
• Os valores ustride e vstride indicam quantos valores float existem entre cada elemento do vetor no sentido horizontal (ustride) e vertical (vstride)
• Os parâmetros uorder e vorder devem conter a quantidade de elementos nos dois sentidos
• *pontos é um ponteiro para a estrutura de dados onde são guardados os pontos de controle.
Superfícies de Bézier
Explicação mais Detalhada
Finalmente, glEvalCoord2f(i,j) é a função que avalia os pontos de controle nas coordenadas definidas por glMap2f
Relembrando da Teoria: Curva de Bézier de grau 3
BB GM
T
B
B
B
B
ttttP
3
2
1
0
23
0001
0033
0363
1331
1)(
33
22
12
03 )1(3)1(3)1()( BtBttBttBttP
Parâmetros avaliados com o uso da função glEvalCoord2f
Pontos de controle
Superfícies de Bézier
// Função de Avaliação (Chamada de dentro das macros de desenho (glBegin/Ebd))
// Traça a superfície
for(float j=0; j<=1.01; j+=delta)
{
glBegin(GL_LINE_STRIP); // desenha (avalia) uma dimensão
for(float i=0; i<=1.01; i+=delta)
glEvalCoord2f(i,j);
glEnd();
glBegin(GL_LINE_STRIP); // desenha (avalia) a segunda dimenção
for(float i=0; i<=1.01; i+=delta)
glEvalCoord2f(j,i);
glEnd();
}
Superfícies de Bézier
Sugestão de ClallBacks para serem usadas:
// Registra a função callback para eventos de botões do mouse
glutMouseFunc(GerenciaMouse);
// Registra a função callback para eventos de movimento do mouse
glutMotionFunc(GerenciaMovim);
// Registra a função callback para tratamento das teclas normais
glutKeyboardFunc (Teclado);
// Registra a função callback para tratamento das teclas especiais
glutSpecialFunc (TeclasEspeciais);
Superfícies de Bézier
// Função callback para eventos de botões do mouse
void GerenciaMouse(int button, int state, int x, int y)
{
if (state==GLUT_DOWN)
{
// Salva os parâmetros atuais
x_ini = x;
y_ini = y;
obsX_ini = obsX;
obsY_ini = obsY;
obsZ_ini = obsZ;
rotX_ini = rotX;
rotY_ini = rotY;
bot = button;
}
else bot = -1;
}
Superfícies de Bézier
// Função callback para eventos de movimento do mousevoid GerenciaMovim(int x, int y){
// Botão esquerdo ?if(bot==GLUT_LEFT_BUTTON){ // Calcula diferenças int deltax = x_ini - x; int deltay = y_ini - y; // E modifica ângulos rotY = rotY_ini - deltax/SENS_ROT; rotX = rotX_ini - deltay/SENS_ROT;}
Superfícies de Bézier
// Função callback para eventos de movimento do mouse (Continuação)
// Botão direito ?else if(bot==GLUT_RIGHT_BUTTON){
// Calcula diferençaint deltaz = y_ini - y;// E modifica distância do observadorobsZ = obsZ_ini + deltaz/SENS_OBS;
}// Botão do meio ?else if(bot==GLUT_MIDDLE_BUTTON){
// Calcula diferençasint deltax = x_ini - x;int deltay = y_ini - y;// E modifica posiçõesobsX = obsX_ini + deltax/SENS_TRANSL;obsY = obsY_ini - deltay/SENS_TRANSL;
}PosicionaObservador();glutPostRedisplay();
}
Superfícies de Bézier
// Função responsável por inicializar parâmetros e variáveis (Chamada na Função Principal)void Inicializa (void){
// Define significado dos pontos de controle (explicação acima)glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &pontos[0][0][0]);// Ativa geração de coordenadasglEnable(GL_MAP2_VERTEX_3); (explicação acima)
// Define a cor de fundo da janela de visualização como brancaglClearColor(1.0f, 1.0f, 1.0f, 1.0f);
// Inicializa a variável que especifica o ângulo da projeção// perspectivaangle=60;
// Inicializa as variáveis usadas para alterar a posição do // observador virtualrotX = 0;rotY = 0;obsX = obsY = 0;obsZ = 5;
}
Superfícies de Bézier
// Função callback para tratar eventos de teclas especiaisvoid TeclasEspeciais (int tecla, int x, int y) {
switch (tecla){
case GLUT_KEY_HOME: if(angle>=10) angle -=5;break;
case GLUT_KEY_END: if(angle<=150) angle +=5;break;
}EspecificaParametrosVisualizacao();glutPostRedisplay();
}
Superfícies de Bézier
// Função callback chamada para gerenciar eventos de teclasvoid Teclado (unsigned char key, int x, int y) {
switch(key){
case '-': if(prec>2) prec--;break;
case '+': prec++;break;
case 27: exit(0);break;
}glutPostRedisplay();
}
Superfícies de Bézier
// Função callback chamada quando o tamanho da janela é alterado void AlteraTamanhoJanela(GLsizei w, GLsizei h){
// Para previnir uma divisão por zeroif ( h == 0 ) h = 1;
// Especifica as dimensões da viewportglViewport(0, 0, w, h);
// Calcula a correção de aspectofAspect = (GLfloat)w/(GLfloat)h;
EspecificaParametrosVisualizacao();}
Superfícies de Bézier
// Função usada para especificar o volume de visualizaçãovoid EspecificaParametrosVisualizacao(void){
// Especifica sistema de coordenadas de projeçãoglMatrixMode(GL_PROJECTION);// Inicializa sistema de coordenadas de projeçãoglLoadIdentity();
// Especifica a projeção perspectiva(angulo,aspecto,zMin,zMax)gluPerspective(angle,fAspect,0.1,1200);
PosicionaObservador();}
Superfícies de Bézier
Explicação mais Detalhada// Especifica a projeção perspectiva(angulo,aspecto,zMin,zMax)GLvoid gluPerspective( GLdouble fovy, GLdouble aspect, GLdouble nearClip, GLdouble farClip )
•Um Grande fovy é como olhar através de uma lente grande •Um pequeno fovy é como olhar através de um telescópio•O aspecto é a largura/altura do plano de projeção
Superfícies de Bézier
// Função usada para especificar a posição do observador virtualvoid PosicionaObservador(void){
// Especifica sistema de coordenadas do modeloglMatrixMode(GL_MODELVIEW);// Inicializa sistema de coordenadas do modeloglLoadIdentity();// Posiciona e orienta o observadorglTranslatef(-obsX,-obsY,-obsZ);glRotatef(rotX,1,0,0);glRotatef(rotY,0,1,0);
}
Superfícies de Bézier
// Função callback de redesenho da janela de visualizaçãovoid Desenha(void){
// Limpa a janela de visualização com a cor // de fundo definida previamenteglClear(GL_COLOR_BUFFER_BIT);
// Altera a cor do desenho para pretoglColor3f(0.0f, 0.0f, 0.0f);
// Calcula incremento de acordo com o total// de pontos intermediáriosfloat delta = 1.0/(float)prec;
Superfícies de Bézier
// Função callback de redesenho da janela de visualização (Continuação)// Traça a superfície
for(float j=0; j<=1.01; j+=delta){
glBegin(GL_LINE_STRIP);for(float i=0; i<=1.01; i+=delta)
glEvalCoord2f(i,j);glEnd();glBegin(GL_LINE_STRIP);for(float i=0; i<=1.01; i+=delta)
glEvalCoord2f(j,i);glEnd();
}
Superfícies de Bézier
// Função callback de redesenho da janela de visualização (Continuação)
// Muda a cor para vermelhoglColor3f(1.0f, 0.0f, 0.0f);
// Define tamanho de um pontoglPointSize(5.0);
// Desenha os pontos de controleglBegin(GL_POINTS);for(int i=0; i<4; ++i) for(int j=0; j<4; ++j) glVertex3fv(pontos[i][j]);glEnd();
// Executa os comandos OpenGLglFlush();
}