ctrlPoints . add (6f, -4f, 0f); // ControlctrlPoints . add (4f, 0f, 0f); // EndDepois <strong>de</strong> limpar o color buffer, criamos o mapping para a curva utilizando a função glMap1f:gl. glClear ( GL2 . GL_COLOR_BUFFER_BIT );float umin = 0f; // Valor minimo do ufloat umax = 100 f; // Valor maximo do ugl. glMap1f (GL2 . GL_MAP1_VERTEX_3 , // Tipo <strong>de</strong> dados geradosumin , // Valor minimo do uumax , // Valor maximo do u3, // Distancia entre pontosctrlPoints . size () , // Numero <strong>de</strong> pontos <strong>de</strong> controloctrlPoints . toFloatBuffer () // FloatBuffer contendo pontos <strong>de</strong> controlo);O primeiro argumento da função glMap1f <strong>de</strong>fine o tipo <strong>de</strong> evaluator a utilizar para gerar os vértices da linha.O segundo e terceiros argumentos <strong>de</strong>finem o valor <strong>de</strong> u para o ponto inicial da curve e o valor <strong>de</strong> u para o pontofinal da curva. Os pontos intermédios representam uma posição na curva 1 .O terceiro argumento representa o número <strong>de</strong> elementos em cada posição do array contendo os pontos <strong>de</strong>controlo (neste caso um FloatBuffer). Para o programa Bezier2D.java, estamos a utilizar as coor<strong>de</strong>nadas x,y e z, daí o valor ser 3. O quarto argumento <strong>de</strong>fine o número <strong>de</strong> pontos <strong>de</strong> controlo que preten<strong>de</strong>mos utilizar efinalmente o último argumento é o buffer (ou array) contendo os pontos <strong>de</strong> controlo.Por uma questão <strong>de</strong> conveniência, foi criado o método toFloatBuffer() na classe GLVectorList que <strong>de</strong>volveum FloatBuffer contendo as posições x, y e z dos vectores adicionados (via add(x, y, z)).No passo seguinte activamos o evaluator que utilizámos na função glMap1f e <strong>de</strong>senhamos os vértices geradoscom a ajuda da função glEvalCoord:// Activar o Evaluatorgl. glEnable ( GL2 . GL_MAP1_VERTEX_3 );// Desenhar os vertices da curvagl. glColor3f (0f, 0f, 0f);gl. glBegin ( GL2 . GL_LINE_STRIP );for ( float i= umin ; i< umax ; i ++)gl. glEvalCoord1f (i);gl. glEnd ();A fim <strong>de</strong> facilitar a compreensão dos pontos <strong>de</strong> controlo, <strong>de</strong>senhamo-los também:// Desenhar Pontos <strong>de</strong> Contrologl. glPointSize (5.0 f);gl. glColor3f (1f, 0f, 0f);gl. glBegin ( GL2 . GL_POINTS );for ( GLVector point : ctrlPoints )point . draw ();gl. glEnd ();O resultado final do nosso programa Bezier2D po<strong>de</strong> ser visualizado na Figura 10.12.Por uma questão <strong>de</strong> eficiência e a fim <strong>de</strong> tornar o código mais compacto, o OpenGL permite-nos <strong>de</strong>senhar acurva utilizando apenas as 2 funções glMapGrid e glEvalMesh, <strong>de</strong> forma que o código:gl. glBegin ( GL2 . GL_LINE_STRIP );for ( float i= umin ; i< umax ; i ++)gl. glEvalCoord1f (i);gl. glEnd ();Seria re-escrito da seguinte forma:// Mapear uma grelha <strong>de</strong> 100 pontos com u min=0 e u max =100gl. glMapGrid1d (100 , umin , umax );// Fazer o evaluate da grelha anterior utilizando linhas ( GL_LINE )gl. glEvalMesh1 ( GL2 . GL_LINE , ( int )umin , ( int ) umax );1 Neste caso, o valor 50 representa o ponto no meio da curva, o 25 a um quarto da curva, etc. . .107
Figura 10.12: Curva <strong>de</strong> Bézier 2D10.2.5 Superfícies 3DA forma <strong>de</strong> criar uma superfície <strong>de</strong> Bézier é muito semelhante à criação das curvas. Adicionamos apenas oparâmetro v que correspon<strong>de</strong> a um segundo domínio. O código completo do exemplo seguinte po<strong>de</strong> ser consultadono Apêndice C.8 referente ao programa Bezier3D.java.A diferença, à partida, em relação ao exemplo Bezier2D, é que neste utilizamos 3 conjuntos <strong>de</strong> 3 pontos <strong>de</strong>controlo cada.Começamos então por <strong>de</strong>finir os pontos <strong>de</strong> controlo, 3 na direcção <strong>de</strong> u por 3 na direcção <strong>de</strong> v:// Definir Pontos <strong>de</strong> ControloctrlPoints = new GLVectorList ();// v0ctrlPoints . add ( -4f, 0f, 4f); // Start (u0)ctrlPoints . add ( -2f, 4f, 4f); // Control (u0)ctrlPoints . add (4f, 0f, 4f); // End (u0)// v1ctrlPoints . add ( -4f, 0f, 0f); // Start (u1)ctrlPoints . add ( -2f, 4f, 0f); // Control (u1)ctrlPoints . add (4f, 0f, 0f); // End (u1)// v2ctrlPoints . add ( -4f, 0f, -4f); // Start (u2)ctrlPoints . add ( -2f, 4f, -4f); // Control (u2)ctrlPoints . add (4f, 0f, -4f); // End (u2)Seguidamente geramos o mapa bidmimensional <strong>de</strong> pontos para a superfície, utilizando a função glMap2f como primeiro argumento tendo o valor GL2.GL MAP2 VERTEX 3, em vez da função glMap1f, da seguinte forma:float umin = 0f; // Valor minimo do ufloat umax = 10f; // Valor maximo do ufloat vmin = 0f; // Valor minimo do vfloat vmax = 10f; // Valor maximo do vgl. glMap2f (GL2 . GL_MAP2_VERTEX_3 , // Tipo <strong>de</strong> dados geradosumin , // Valor minimo do uumax , // Valor maximo do u108