Jonh Edson Ribeiro de Carvalho | IC-UFFComputação Visual e Interfaces |
|||||||||||||||||
|
|||||||||||||||||
Tutorial OpenGL | |||||||||||||||||
Capítulo 7. Curvas no plano
O propósito desta lição é mostrar como gerar em um plano as curvas paramétricas mais comuns no OpenGL: as curvas de Bézier e as NURBS (Non Uniform Rational B-Splines). A forma destas curvas é controlada pelo posicionamento dos vértices de um polígono característico, cuja influência será estudada de forma interativa no programa exemplo. Será estudada também a influência dos vetores de nós sobre as NURBS, vetores estes que servem para definir a região de influência de cada vértice do polígono característico na forma da curva. É introduzido também o uso de uma nova função do GLUT: glutMotionFunc(), ativada quando o mouse é movimentado pela janela enquanto um ou mais botões são pressionados. O programa utilizado nesta lição permite que o usuário controle a forma de uma curva através da seleção e movimentação dos vértices (destacados em vermelho) de um polígono (em amarelo), como mostra a Figura 7-1. O programa usado para modelar as splines é mostrado no Exemplo 7-1. As teclas b e n definem o tipo de curva que será desenhada: Bézier ou NURBS, respectivamente. Exemplo 7-1. programa splines2d.c
Para compilar e executar o programa splines2d.c, salve-o juntamente com o arquivo Makefile em um diretório e execute a seguinte seqüência de comandos:
7.1. Descrição do programa splines2d.c
Define o número de vértices do polígono característico (variável nVertices) e as posições no espaço dos seus respectivos vértices (vetor vertices).
As variáveis largura e altura armazenam a largura e a altura da janela corrente, em pixels. mudaCurva grava o estado da curva; quando mudaCurva=1, a posição dos vértices pode ser alterada; quando mudaCurva=0, a curva permanece inalterada com o movimento do mouse. A variável verticeCorrente indica o vértice cuja posição poderá ser alterada através da movimentação do mouse.
Define as coordenadas do volume de recorte a ser utilizado na projeção ortográfica.
A variável nc contém a referência para a spline que irá modelar a curva usando NURBS. nos e nNos são o vetor de nós e o número de nós neste vetor, respectivamente.
Define as matrizes de viewport, de modelo e de projeção para a cena. Estas matrizes serão usadas no cálculo da posição do mouse no mundo real.
Caso a spline seja do tipo Bézier, o traçado da curva se com o uso de avaliadores. Tais evaluators proporcionam uma forma de utilizar o mapeamento de polinômios para produzir vértices, coordenadas de texturas e cores, baseados em funções de base de Bernstein, ou de Bézier. A função glMap1f() define um avaliador (evaluator) unidimesional. Neste caso, os valores gerados por esta função são utilizados pelos estágios posteriores do processamento como se houvessem sido gerados utilizando a função glVertex*(). A função glMap1f() possui o seguinte protótipo:
O parâmetro target especifica o tipo de valores gerados pelo evaluator; neste caso, especifica que cada ponto de controle é usado para mapear três valores x, y e z. Comandos internos glVertex*() são gerados quando este mapeamento é realizado. u1 e u2 especificam a faixa de mapeamento linear para u, ou seja, a faixa de variação do parâmetro que define a curva; neste caso [0,1]. stride especifica o número de elementos entre o início de um ponto de controle e o início do ponto de controle seguinte; como cada ponto de controle possui três coordenadas, stride=3 para este exemplo. O parâmetro order especifica o número de pontos de controle para a curva (6 pontos). Finalmente, o parâmetro *points deve conter a posição do primeiro ponto do polígono de controle.
Neste laço, quando a função glEvalCoord1f() é chamada, o valor do ponto a ser traçado na spline é calculado (ou avaliado) para o valor passado como referência para esta função. Quando o laço terminar, um conjunto de pontos interligados (via GL_LINE_STRIP) irá compor a forma da curva de Bézier, usando o polígono de controle especificado a priorio com a função glMap1f().
Se a curva a ser desenhada for do tipo NURBS, então as funções gluBeginCurve() e gluEndCurve() serão utilizadas para demarcar o início e o fim do seu traçado. A função usada para desenhar esta classe de curvas é gluNurbsCurve, cujos parâmetros são bastante semelhantes aos da função glMap1f(), acrescentando apenas a referência para a curva, nc e os dados do vetor de nós (nos e nNos). A variável nc é iniciada na função init().
O diâmetro dos pontos rasterizados é mudado para facilitar a visualização dos vértices do polígono de controle (5 pixels).
A função gluNewNurbsRenderer() cria um objeto NURBS, que pode ser referenciado durante a chamada para o traçado de curvas desta caterogia. A função gluNurbsProperty() aqui colocada define o espaçamento máximo, em pixels, usado na amostragem de pontos, durante o traçado da curva, geralmente traçada por aproximação poligonal. Neste exemplo, pontos adjacentes do polígono que aproxima a curva têm espacamento máximo de 5 pixels.
As chamadas às funções glGetIntergerv e glGetDoublev gravam em matrizViewport, matrizModelview e matrizProjecao as matrizes de viewport, de modelo e de projeção. Na matriz de viewport ficam armazenadas as coordenadas da origem da janela, seguidas pela sua altura e largura.
A função proximidade() compara os valores das distâncias entre a posição do mouse em coordenadas do mundo real, (wx, wy), com as coordenadas de cada vértice do polígono de controle, em busca do vértice mais próximo. Caso a distância entre a posição do mouse e o vértice mais próximo seja maior que uma dada tolerância, o vértice não será selecionado para alteração.
A variável yreal armazena a coordenada y (em pixels) da posição do cursor, assumindo origem na parte inferior esquerda da janela. A função gluUnProject() serve para mapear as coordenadas da janela para as coordenadas do mundo real. Com base nas coordenadas do mouse na janela, x e yreal, nas matrizes de modelo, de projeção e de viewport, e assumindo a posição z=0, a função gluUnProject() calcula as respectivas coordenadas wx, wy e wz da posição do mouse no mundo real, possibilitando a comparação das distâncias para cada vértice do polígono característico.
A função motion() é chamada cada vez que o mouse é movimentado na janela e um ou mais botões encontra-se pressionado. Caso a alteração dos vértices esteja habilitada, as coordenadas da posição do mouse são mapeadas para o mundo real e atribuídas ao vértice a ser modificado.
Define a função de movimentação do mouse para a janela corrente. A função passada como parâmetro deve possuir o seguinte protótipo:
Os parâmetros x e y passados para esta função indicam a posição do mouse em coordenadas relativas à janela. Caso seja necessário, a função glutPassiveMotionFunc pode ser utilizada para monitorar o movimento do mouse quando não há botões pressionados, e possui o mesmo protótipo da função glutMotionFunc |
|||||||||||||||||
CopyLeft Webmaster |Atualizado em 22/11/2003 | |||||||||||||||||
Contato Pesquisas e Projetos Publicações Home |