Laboratorio de Computación Gráfica I

Laboratorio 015: Objetos 3D

publicado a la‎(s)‎ 10 sept 2012, 19:57 por Hernan Nina Hanco   [ actualizado el 3 jun 2014, 15:57 ]

I) Objetivo

  • Implementar los algoritmos de recorte.

II) Marco conceptual

    Ver Guía de Computación Gráfica


III) Prácticas

1) Dibujar un poligono.
IV) Tarea
  • Implementar Algoritmos de recorte.

Laboratorio 019: Algoritmos de relleno de áreas

publicado a la‎(s)‎ 14 ago 2012, 12:56 por Hernan Nina Hanco   [ actualizado el 3 jun 2014, 15:58 ]

I) Objetivo

  • Implementar transformaciones de inclinación y reflexión considerando casos de ejes básicos y genéricos.

II) Marco conceptual

    Ver Guía de Computación Gráfica


III) Prácticas

1) Dibujar un poligono.
IV) Tarea
  • Demostraciones de reflexiones

Laboratorio 018: Algoritmos de recorte

publicado a la‎(s)‎ 14 ago 2012, 12:55 por Hernan Nina Hanco   [ actualizado el 3 jun 2014, 15:58 ]

I) Objetivo

  • Implementar los algoritmos de recorte.

II) Marco conceptual

    Ver Guía de Computación Gráfica


III) Prácticas

1) Dibujar un poligono.
package geometrias.rellenoareas;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author hernan
 */
public class Poligono {

    private List<Punto> vertices;
    private List<Punto> vectores;
    private List<Punto> productosVectoriales;
    private List<Punto> vectoresExtension;

    /*
     * 
     */
    public Poligono(List<Punto> vertices) {
        this.vertices = vertices;
    }
    /*
     * Hallar vectores de poligono
     */

    public List<Punto> getVectoresExtension() {
        return vectoresExtension;
    }

    public List<Punto> hallarVectores() {
        // cálcular vectores del poligono
        vectores = new ArrayList<Punto>();
        int nroVertices = vertices.size();
        for (int i = 0; i < nroVertices - 1; i++) {
            Punto vector = diferenciaVector(vertices.get(i+1), vertices.get(i));
            vectores.add(vector);
        }
        // calcular el últiimo vector
        Punto ultimoVector = diferenciaVector(vertices.get(0), vertices.get(nroVertices - 1));
        vectores.add(ultimoVector);
        return vectores;
    }
    
    /*
     * Hallar vectores resultante del producto vectorial
     */
    public List<Punto> hallarVectoresProductoVectorial()
    {
        List<Punto> temp= new ArrayList<Punto>();
        List<Punto> temp1 = new ArrayList<Punto>();
        
        int numeroVectores = this.vectores.size();
        for (int i=0;i<numeroVectores-1;i++)
        {
            Punto producto = productoVectorial(vectores.get(i), vectores.get(i+1));
            if (producto.getZ()<0)
            {
                temp1.add(vectores.get(i));
            }
            temp.add(producto);
        }
        // ultimo punto
        Punto ultimoPunto = productoVectorial(vectores.get(numeroVectores-1), vectores.get(0));
        temp.add(ultimoPunto);
        this.vectoresExtension = temp1;
        return temp;
    }

    /*
     * Hallar el vector
     */
    public Punto diferenciaVector(Punto p1, Punto p2) {
        Punto p = new Punto(p1.getX() - p2.getX(),
                p1.getY() - p2.getY(),
                p1.getZ() - p2.getZ());
        return p;
    }
    public Punto productoVectorial(Punto vector1, Punto vector2)
    {
        return new Punto(
                vector1.getY()*vector2.getZ() - vector1.getZ()*vector2.getY(),
                - (vector1.getX()*vector2.getZ() - vector1.getZ()*vector2.getX()),
                vector1.getX()*vector2.getY() - vector1.getY()*vector2.getX()
                );
    }

    public static void main(String[] args) {
        List<Punto> vertices = new ArrayList<Punto>();
        vertices.add(new Punto(0, 0, 0));
        vertices.add(new Punto(1, 0, 0));
        vertices.add(new Punto(2, 1, 0));
        vertices.add(new Punto(3, 0, 0));
        vertices.add(new Punto(3, 3, 0));
        vertices.add(new Punto(0, 3, 0));


        Poligono poligono = new Poligono(vertices);
        List<Punto> vectores = poligono.hallarVectores();
        System.out.println("Vectores: " + vectores);
        List<Punto> productos = poligono.hallarVectoresProductoVectorial();
        System.out.println("Productos: " + productos);
        System.out.println("Vector extension: " + poligono.vectoresExtension);
    }
}
IV) Tarea
  • Implementar programas con algoritmos de Recorte de Nicholl-Lee-Nicholl y Cohem Sutherland.

Laboratorio 017: Transformaciones Geométricas 2D extendidas

publicado a la‎(s)‎ 14 ago 2012, 12:54 por Hernan Nina Hanco   [ actualizado el 3 jun 2014, 15:59 ]

I) Objetivo

  • Desarrollar una aplicación gráfica para mostrar la implementación de transformaciones compuestas, escalamiento en punto fijo, rotaciones en punto pivot, inclinación y reflexión.

II) Marco conceptual

    Ver Guía de Computación Gráfica


III) Prácticas

1) Implementar las matrices homogéneas para la traslación, rotación y escalonamiento. Seguidamente implemente las operaciones de multiplicación de matrices de 3X3 y 3X1 para resolver transformaciones compuestas. Finalmente muestre gráficamente el uso de transformaciones compuestas para la siguiente figura.
a) 
b) 
2) Muestre gráficamente las operaciones de reflexión para las siguientes situaciones. (Utilice cualquier polígono)
a) Reflexión sobre el eje X
b) Reflexión sobre el eje Y
c) Reflexión sobre el origen de coordenadas
d) Reflexión al rededor de un punto del plano XY
e) Reflexión sobre el eje representado con la línea y=x
d) Reflexión sobre el eje representado con la línea y=-x
e) Reflexión Sobre cualquier eje de linea y=mx+b

3) Muestre gráficamente las operaciones de inclinación en el eje X y eje Y. Considere cualquier polígono.


IV) Tarea
  • Implementar un programa para realizar las operaciones de transformación.

Laboratorio 016: Transformaciones Geométricas 2D Básicas

publicado a la‎(s)‎ 19 jul 2012, 8:50 por Hernan Nina Hanco   [ actualizado el 3 jun 2014, 16:02 ]

I) Objetivo

  • Implementar transformaciones geométricas 2D básicas de traslación, rotación y escalamiento de Poligonos.

II) Marco conceptual

    Ver Guía de Computación Gráfica


III) Prácticas

1) Transformaciones básicas
/*
 * Creado el 23 de mayo, 2012 por Hernán Nina Hanco
 *
 * Este trabajo es parte del proyecto CG1, que corresponde a la 
 * implementación de algoritmos de Dibujo de graficas.
 * 
 * Universidad Nacional de San Antonio Abad del Cusco
 * Carrera Profesional de Ingeniería Informática y de Sistemas
 * Asignatura: Computación Gráfica I
 */
package geometrias.transformaciones;
/*
 * Transformaciones básicas
 * @author Hernan Nina Hanco 
 */

import javax.media.opengl.*;

public class Renderer_Transformaciones2DBasicas implements GLEventListener {

    protected GL2 gl;
    /* Vertices de un triangulo */
    static float vertices[][] = {
        {100.0f, 0.0f},
        {0.0f, 100.0f},
        {-100.0f, 0.0f}
    };
    static float[][] matrizIdentidad = {
        {1.0f, 0.0f, 0.0f},
        {0.0f, 1.0f, 0.0f},
        {0.0f, 0.0f, 1.0f}
    };

    /*
     * Inicializar graficador OpenGL
     */
    @Override
    public void init(GLAutoDrawable gLDrawable) {
        // Provee un objeto que enlaza las APIs del OpenGL
        // Que se encargara de realizar las instrucciones de dibujos 
        gl = gLDrawable.getGL().getGL2();

        // Color de fondo del GLCanvas
        gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT);

        // definir el color del pincel
        gl.glColor3f(1.0f, 0.0f, 0.0f);

    }
    /*
     * Método para actualizar el dibujo cuando,
     * se modifica el tamaño de la ventana.
     */

    @Override
    public void reshape(GLAutoDrawable glad, int x, int y, int width,
            int height) {

        // 7. Especificar el área de dibujo (frame) utilizamos coordenadas
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrtho(-width, width, -height, height, -1.0, 1.0);
    }

    @Override
    public void dispose(GLAutoDrawable glad) {
        // no implementado
    }

    /*
     * Inicializar y presentar el dibujo de OpenGL
     */
    @Override
    public void display(GLAutoDrawable drawable) {
        // Establecer el tamaño y color del punto     
        gl.glPointSize(1);
        gl.glColor3f(0.0f, 0.0f, 1.0f);
        dibujarTriangulo();
        // trasladar triangulo
        trasladarTriangulo(150.0f, 0.0f);
        dibujarTriangulo();
    }

    /*
     * Operaciones de transformaciones
     */
    protected void trasladarPunto2D(float tx, float ty) {
    }

    private void dibujarTriangulo() {

        gl.glBegin(GL.GL_TRIANGLES);
        gl.glVertex2f(vertices[0][0], vertices[0][1]);
        gl.glVertex2f(vertices[1][0], vertices[1][1]);
        gl.glVertex2f(vertices[2][0], vertices[2][1]);
        gl.glEnd();

    }

    private void trasladarTriangulo(float tx, float ty) {
        trasladarPunto2D(vertices[0], tx, ty);
        trasladarPunto2D(vertices[1], tx, ty);
        trasladarPunto2D(vertices[2], tx, ty);

    }

    private void trasladarTrianguloHomo(float tx, float ty) {
        trasladarPuntoHomo2D(vertices[0], tx, ty);
        trasladarPuntoHomo2D(vertices[1], tx, ty);
        trasladarPuntoHomo2D(vertices[2], tx, ty);

    }

    private void trasladarPunto2D(float[] punto, float tx, float ty) {
        punto[0]=punto[0]+tx;
        punto[1]=punto[1]+ty;
    }
    private void trasladarPuntoHomo2D(float[] punto, float tx, float ty)
    {
        float[] puntoHomo = {punto[0], punto[1], 1.0f};
        
    }
    private void multiplicarAPunto(float[][] matriz, float[] puntoHomo){

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                //puntoHomo[j] = matriz[i,j]*puntoHomo[j];
            }
        }
        
    }
}
.
IV) Tarea
  • Implementar un programa para realizar la traslación, rotación y escalamiento de una figura poligonal.

Laboratorio 015: Atributos de primitivas

publicado a la‎(s)‎ 17 jul 2012, 12:43 por Hernan Nina Hanco   [ actualizado el 3 jun 2014, 16:03 ]

I) Objetivo

  • Implementar algoritmos de atributos de primitivas de Puntos, Líneas, Curvas y Caracteres.

II) Marco conceptual

    


Ver Guía de Computación Gráfica


III) Prácticas

1) Grosor de punto.

void lineDDA(int x0, int y0, int xn, int yn) {

       int x;

       float m, y;

       // Calcular la pendiente

       m = (float) (yn - y0) / (xn - x0);

       x = x0;

       y = y0;

       // Esto solo funciona para una línea

  // de pendiente positiva y menor a 1

       while (x < xn + 1) {

           //Dibujar un pixel en la ventana

           dibujarPunto(x, Math.round(y));

           /* Posición del siguiente pixel */

           x++;

           y += m;

       }

   }
IV) Tarea
  • Implementar una aplicación para dibujar líneas arbitrarias con un determinado grosor de Línea.
  • Modifique la aplicación anterior para evitar las puyas en las líneas de grosor utilizando extremos cuadrado, redondeado y biselado.
  • Implementar una aplicación para dibujar polilineas de un determinado grosor de línea evitar los huecos en las esquinas.
  • Implementar una aplicación para dibujar una circunferencia con un determinado grosor de línea.
  • Implementar una aplicación para dibujar una elipse con un determinado grosor de línea.

Laboratorio 014: Relleno poligonal

publicado a la‎(s)‎ 5 jul 2012, 5:15 por Hernan Nina Hanco   [ actualizado el 3 jun 2014, 16:03 ]

I) Objetivo

  • Implementar algoritmos de relleno poligonal descritos en la teoría de la asignatura.

II) Marco conceptual

    Ver Guía de Computación Gráfica


III) Prácticas

1) Dibujar un polígono utilizando polilineas cerradas.

Clase Renderer_RellenoPoligonal

/*
 * Creado el 23 de mayo, 2012 por Hernán Nina Hanco
 *
 * Este trabajo es parte del proyecto CG1, que corresponde a la 
 * implementación de algoritmos de Dibujo de graficas.
 * 
 * Universidad Nacional de San Antonio Abad del Cusco
 * Carrera Profesional de Ingeniería Informática y de Sistemas
 * Asignatura: Computación Gráfica I
 */
package geometrias.rellenoareas;
/*
 * Dibujo de líneas con pendiente -1<m<1
 * @author Hernan Nina Hanco 
 */

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.opengl.*;

public class Renderer_RellenoPoligonal implements GLEventListener {

    static final Logger logger = Logger.getLogger("BasicLoggingExample");
    protected GL2 gl;
    /*
     * Inicializar graficador OpenGL
     */

    @Override
    public void init(GLAutoDrawable gLDrawable) {
        logger.log(Level.INFO, "método - init");
        // Provee un objeto que enlaza las APIs del OpenGL
        // Que se encargara de realizar las instrucciones de dibujos 
        gl = gLDrawable.getGL().getGL2();

        // Color de fondo del GLCanvas
        gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT);

        // definir el color del pincel
        gl.glColor3f(1.0f, 0.0f, 0.0f);

    }
    /*
     * Método para actualizar el dibujo cuando,
     * se modifica el tamaño de la ventana.
     */

    @Override
    public void reshape(GLAutoDrawable glad, int x, int y, int width,
            int height) {
        logger.log(Level.INFO, "Reshape");
        // 7. Especificar el área de dibujo (frame) utilizamos coordenadas
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrtho(-width, width, -height, height, -1.0, 1.0);
    }

    @Override
    public void dispose(GLAutoDrawable glad) {
        // no implementado
    }

    /*
     * Inicializar y presentar el dibujo de OpenGL
     */
    @Override
    public void display(GLAutoDrawable drawable) {
        // Establecer el tamaño y color del punto     
        gl.glPointSize(1);
        gl.glColor3f(0.0f, 0.0f, 1.0f);

        // Dibujar polilinea cerrada
        List<Punto> vertices = new ArrayList<Punto>();
        vertices.add(new Punto(0, 0, 0));
        vertices.add(new Punto(100, 0, 0));
        vertices.add(new Punto(200, 100, 0));
        vertices.add(new Punto(300, 0, 0));
        vertices.add(new Punto(300, 300, 0));
        vertices.add(new Punto(0, 300, 0));
        dibujarPolilineasCerrada(vertices);
        // Identificar poligono concavo
        // identificarPoligonoConcavo();
    }
    /*
     * Dibujar un poligono utilizando polilinea cerrada
     */
    private void dibujarPolilineasCerrada(List<Punto> vertices) {
        int numeroVertices = vertices.size();
        for (int i = 0; i < numeroVertices - 1; i++) {
            int x0 = vertices.get(i).getX();
            int y0 = vertices.get(i).getY();
            int xn = vertices.get(i + 1).getX();
            int yn = vertices.get(i + 1).getY();
            lineaBresenham(x0, y0, xn, yn);
        }
        // cerrar la figura
        int x0 = vertices.get(numeroVertices - 1).getX();
        int y0 = vertices.get(numeroVertices - 1).getY();
        int xn = vertices.get(0).getX();
        int yn = vertices.get(0).getY();
        lineaBresenham(x0, y0, xn, yn);
    }
    /*
     * Dibujar línea arbitraria con metodo bresenham 
     */
    public void lineaBresenham(int x0, int y0, int xn, int yn) {
        int dx, dy, incrE, incrNE, d, x, y, flag = 0;

        if (xn < x0) {
            //intercambiar(x0,xn);
            int temp = x0;
            x0 = xn;
            xn = temp;

            //intercambiar(y0,yn);
            temp = y0;
            y0 = yn;
            yn = temp;
        }
        if (yn < y0) {
            y0 = -y0;
            yn = -yn;
            flag = 10;
        }

        dy = yn - y0;
        dx = xn - x0;

        if (dx < dy) {
            //intercambiar(x0,y0);
            int temp = x0;
            x0 = y0;
            y0 = temp;

            //intercambiar(xn,yn);
            temp = xn;
            xn = yn;
            yn = temp;

            //intercambiar(dy,dx);
            temp = dy;
            dy = dx;
            dx = temp;
            flag++;
        }

        x = x0;
        y = y0;
        d = 2 * dy - dx;
        incrE = 2 * dy;
        incrNE = 2 * (dy - dx);

        while (x < xn + 1) {
            escribirPixel(x, y, flag); /* Dibujar punto */
            x++; /* siguiente pixel */
            if (d <= 0) {
                d += incrE;
            } else {
                y++;
                d += incrNE;
            }
        }
    }

    void escribirPixel(int x, int y, int flag) {
        int xf = x, yf = y;
        if (flag == 1) {
            xf = y;
            yf = x;
        } else if (flag == 10) {
            xf = x;
            yf = -y;
        } else if (flag == 11) {
            xf = y;
            yf = -x;
        }
        dibujarPunto(xf, yf);
    }

    /*
     * Dibujar un punto 
     */
    protected void dibujarPunto(int x, int y) {
        gl.glPointSize(2);
        gl.glBegin(GL.GL_POINTS);
        gl.glVertex2i(x, y);
        gl.glEnd();
    }
}

Resultado:

IV) Tarea
1) Implementar un método para Identificar si el polígono es cóncavo o convexo. Además que pueda eliminar polígonos degenerados.
2) Si en caso fuese el polígono cóncavo dividir el mismo en polígonos convexos. Desarrolle un método para representar gráficamente la división 
3) Una vez que se identifiquen los polígonos convexos, implementar el método para dividirlo en triángulos. Muestre gráficamente el resultado
4) Implementar los métodos necesarios para las Pruebas dentro-fuera, para determinar el interior y exterior de una figura plana compleja. 

Laboratorio 003: Algoritmos de dibujo de círculos

publicado a la‎(s)‎ 27 jun 2012, 17:55 por Hernan Nina Hanco   [ actualizado el 1 oct 2014, 11:54 ]

I) Objetivo

  • Implementar algoritmos para el dibujo de círculos, elipses, hipérbolas y parábolas en base a la teoría de la asignatura.

II) Marco conceptual

    Ver Guía de Computación Grafica: Temas Algoritmos de dibujo de Círculos y Elipses


III) Prácticas


1) Implementar una clase para dibujar el octante de un Círculo con el algoritmo de la ecuación canónica y el punto medio. Además dibujar un circulo con las ecuaciones polares del circulo.

/*
 * Creado el 23 de mayo, 2012 por Hernán Nina Hanco
 *
 * Este trabajo es parte del proyecto CG1, que corresponde a la 
 * implementación de algoritmos de Dibujo de graficas.
 * 
 * Universidad Nacional de San Antonio Abad del Cusco
 * Carrera Profesional de Ingeniería Informática y de Sistemas
 * Asignatura: Computación Gráfica I
 */
package geometrias.curvas;
/*
 * Dibujo de líneas con pendiente -1<m<1
 * @author Hernan Nina Hanco 
 */

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.opengl.*;

public class Renderer_Circulo implements GLEventListener {

    static final Logger logger = Logger.getLogger("BasicLoggingExample");
    protected GL2 gl;
    /*
     * Inicializar graficador OpenGL
     */

    @Override
    public void init(GLAutoDrawable gLDrawable) {
        logger.log(Level.INFO, "método - init");
        // Provee un objeto que enlaza las APIs del OpenGL
        // Que se encargara de realizar las instrucciones de dibujos 
        gl = gLDrawable.getGL().getGL2();

        // Color de fondo del GLCanvas
        gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT);

        // definir el color del pincel
        gl.glColor3f(1.0f, 0.0f, 0.0f);

    }
    /*
     * Método para actualizar el dibujo cuando,
     * se modifica el tamaño de la ventana.
     */

    @Override
    public void reshape(GLAutoDrawable glad, int x, int y, int width,
            int height) {
        logger.log(Level.INFO, "Reshape");
        // 7. Especificar el área de dibujo (frame) utilizamos coordenadas
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrtho(-300, 300, -300, 300, -1.0, 1.0);
        // Dibujar un Sistema de Referencia.
        // dibujarSistemaReferencia(-300, 300, -300, 300);
    }
    /*
     *  
     */

    @Override
    public void dispose(GLAutoDrawable glad) {
        // no implementado
    }

    /*
     * Inicializar y presentar el dibujo de OpenGL
     */
    @Override
    public void display(GLAutoDrawable drawable) {
        int x0, y0, xn, yn, dx, dy;
        // Establecer el tamaño y color del punto     
        gl.glPointSize(1);
        gl.glColor3f(0.0f, 0.0f, 1.0f);

        // Dibujo de Circulos 
        // utilizando diferentes métodos 
        // Se realiza el dibujo en el segundo octante
        // A) Dibujar un Círculo según la ecuación Canónica
        dibujarCirculoCanonica(200, 0, 0);
        // B) Dibujar un Círculo según la ecuación parámetrica polar
        dibujarCirculoPolar(150,0,0);
        // C) Dibujar un Círculo según el algoritmo de punto medio
        dibujarCirculoPuntoMedio(100,0,0);
        // D) Dibujar un Círculo según el algoritmo implementado por OpenGL

    }

    /*
     * Algoritmo de dibujo de un Círculo basado en la ecuación Canónica
     */
    void dibujarCirculoCanonica(int r, int xc, int yc) {
        int x = 0;
        int y = r;

        while (x <= y) {
            this.dibujarPunto(x + xc, y + yc);
            x++;
            double yd = Math.sqrt(r * r - x * x);
            y = (int) Math.round(yd);
        }

    }
    /*
     * Algoritmo para el dibujo de círculo basado en la ecuación parámetrica 
     * polar de la circunferencia.
     */

    void dibujarCirculoPolar(int r, int xc, int yc) {
        // Determinar el angulo de variación
        double theta = Math.toRadians(0);
        // Punto inicial
        int x = r;
        int y = 0;
        // Mientras el angulo no exceda a 360 dibujar puntos
        while (theta <= 2*Math.PI) {
            this.dibujarPunto(x + xc, y + yc);
            // Incrementar el ángulo
            theta=theta+Math.toRadians(5);
            // Cálcular los valores x e y de forma parámetrica
            double xd = r * Math.cos(theta);
            x = (int) Math.round(xd);
            double yd = r * Math.sin(theta);
            y = (int) yd;
        }
    }

    /*
     * Algoritmo para el dibujo de Círculo con el algoritmo de  
     * punto medio
     */
    public void dibujarCirculoPuntoMedio(int r, int xc, int yc) {
        // Punto inicial del círculo
        int x = 0;
        int y = r;
        // Cálcular el parámetro inicial de decisión
        int pk = 1-r;
        
        // verificar el pk para determinar las posiciones de pixel siguuientes
        while (x<=y)
        {
            System.out.println("(x,y)= "+x+","+y+" pk="+pk);
            dibujarPunto(xc+x,yc+y);
            if (pk<0){
                pk+=2*(x+1)+1;
                x++;
            }
            else // pk>=0
            {
                pk+=2*(x+1)+1 - 2*(y-1);
                x++;
                y--;
            }
        }
    }
    /*
     * Algoritmo para el dibujo de Círculo con el algoritmo implementado  
     * por OpenGL.
     */

    void dibujarCirculoOpenGL(int r, int xc, int yc) {
    }

    /*
     * Dibujar un punto 
     */
    protected void dibujarPunto(int x, int y) {
        gl.glPointSize(2);
        gl.glBegin(GL.GL_POINTS);
        gl.glVertex2i(x, y);
        gl.glEnd();
    }
}

Resultado de la aplicación:

IV) Tarea

  1. Modificar la implementación de la práctica para completar el dibujo de los demás octantes del círculo, en los métodos respectivos.

    1. Para el caso del dibujo de círculos con la ecuación general utilizar el muestreo en x o en y según el valor de la pendiente del circulo para evitar la separación de pixeles no uniformes.
    2. Para el caso del dibujo de círculos con la ecuación paramétrica unir la separación de los puntos con rectas para aproximar a la apariencia de un círculo.



    V) Referencias

    • Donalf Hearn, M. Pauline Baker; Gráficas por Computadora con OpenGL; Pearson Prentice Hall; 3° edición; Madrid 2006.
    • Richard S. Jr., Michael Sweet; Programación en OpenGL una guía de referencia
    • Hosting del proyecto esta en: http://code.google.com/p/graficaporc/ 

    Laboratorio 004: Algoritmo punto medio para el dibujo de círculos

    publicado a la‎(s)‎ 27 jun 2012, 17:55 por Hernan Nina Hanco   [ actualizado el 11 jun 2014, 15:28 ]

    I) Objetivo

    • Implementar algoritmos para el dibujo de círculos con el algoritmo de punto medio.

    II) Marco conceptual

        Ver Guía de Computación Grafica: Temas Algoritmos de dibujo de Círculos y Elipses


    III) Prácticas


    1) Implementar una clase para dibujar el octante de un Círculo con el algoritmo de la ecuación canónica y el punto medio. Además dibujar un circulo con las ecuaciones polares del circulo.

    /*
     * Creado el 23 de mayo, 2012 por Hernán Nina Hanco
     *
     * Este trabajo es parte del proyecto CG1, que corresponde a la 
     * implementación de algoritmos de Dibujo de graficas.
     * 
     * Universidad Nacional de San Antonio Abad del Cusco
     * Carrera Profesional de Ingeniería Informática y de Sistemas
     * Asignatura: Computación Gráfica I
     */
    package geometrias.curvas;
    /*
     * Dibujo de líneas con pendiente -1<m<1
     * @author Hernan Nina Hanco 
     */

    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.media.opengl.*;

    public class Renderer_Circulo implements GLEventListener {

        static final Logger logger = Logger.getLogger("BasicLoggingExample");
        protected GL2 gl;
        /*
         * Inicializar graficador OpenGL
         */

        @Override
        public void init(GLAutoDrawable gLDrawable) {
            logger.log(Level.INFO, "método - init");
            // Provee un objeto que enlaza las APIs del OpenGL
            // Que se encargara de realizar las instrucciones de dibujos 
            gl = gLDrawable.getGL().getGL2();

            // Color de fondo del GLCanvas
            gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
            gl.glClear(GL2.GL_COLOR_BUFFER_BIT);

            // definir el color del pincel
            gl.glColor3f(1.0f, 0.0f, 0.0f);

        }
        /*
         * Método para actualizar el dibujo cuando,
         * se modifica el tamaño de la ventana.
         */

        @Override
        public void reshape(GLAutoDrawable glad, int x, int y, int width,
                int height) {
            logger.log(Level.INFO, "Reshape");
            // 7. Especificar el área de dibujo (frame) utilizamos coordenadas
            gl.glMatrixMode(GL2.GL_PROJECTION);
            gl.glLoadIdentity();
            gl.glOrtho(-300, 300, -300, 300, -1.0, 1.0);
            // Dibujar un Sistema de Referencia.
            // dibujarSistemaReferencia(-300, 300, -300, 300);
        }
        /*
         *  
         */

        @Override
        public void dispose(GLAutoDrawable glad) {
            // no implementado
        }

        /*
         * Inicializar y presentar el dibujo de OpenGL
         */
        @Override
        public void display(GLAutoDrawable drawable) {
            int x0, y0, xn, yn, dx, dy;
            // Establecer el tamaño y color del punto     
            gl.glPointSize(1);
            gl.glColor3f(0.0f, 0.0f, 1.0f);

            // Dibujo de Circulos 
                 //  Dibujar un Círculo según el algoritmo de punto medio
            dibujarCirculoPuntoMedio(100,0,0);

        }
        /*
         * Algoritmo para el dibujo de Círculo con el algoritmo de  
         * punto medio
         */
        public void dibujarCirculoPuntoMedio(int r, int xc, int yc) {
            // Punto inicial del círculo
            int x = 0;
            int y = r;
            // Cálcular el parámetro inicial de decisión
            int pk = 1-r;
            
            // verificar el pk para determinar las posiciones de pixel siguuientes
            while (x<=y)
            {
                System.out.println("(x,y)= "+x+","+y+" pk="+pk);
                dibujarPunto(xc+x,yc+y);
                if (pk<0){
                    pk+=2*(x+1)+1;
                    x++;
                }
                else // pk>=0
                {
                    pk+=2*(x+1)+1 - 2*(y-1);
                    x++;
                    y--;
                }
            }
        }
        /*
         * Algoritmo para el dibujo de Círculo con el algoritmo implementado  
         * por OpenGL.
         */

        void dibujarCirculoOpenGL(int r, int xc, int yc) {
        }

        /*
         * Dibujar un punto 
         */
        protected void dibujarPunto(int x, int y) {
            gl.glPointSize(2);
            gl.glBegin(GL.GL_POINTS);
            gl.glVertex2i(x, y);
            gl.glEnd();
        }
    }

    IV) Tarea

    1) Modificar la implementación de la práctica para completar el dibujo de los demás octantes del círculo.

    2) Implementar el algoritmo de punto medio para circulos para el caso del dibujo del circulo desde el punto (r,0)

    3) Cree una clase Renderer_Elipse donde dibuje una elipse utilizando la ecuación canónica, ecuaciones paramétricas polares.

    4) Diseñe un procedimiento para la implementación paralela del algoritmo del punto medio para generación de círculos.



    V) Referencias

    • Donalf Hearn, M. Pauline Baker; Gráficas por Computadora con OpenGL; Pearson Prentice Hall; 3° edición; Madrid 2006.
    • Richard S. Jr., Michael Sweet; Programación en OpenGL una guía de referencia
    • Hosting del proyecto esta en: http://code.google.com/p/graficaporc/ 

    Laboratorio 002: Algoritmos de dibujo de Líneas

    publicado a la‎(s)‎ 6 jun 2012, 18:05 por Hernan Nina Hanco   [ actualizado el 17 sept 2012, 14:46 ]

    I) Objetivo

    • Implementar algoritmos para el dibujo de líneas como parte de las primitivas geométricas.

    II) Marco conceptual

        Ver Guía de Computación Grafica: Temas Algoritmos de dibujo de líneas


    III) Prácticas


    1) Crear una aplicación para dibujar una línea con pendiente positiva y menor a 1. Utilizar varios métodos. Se crea la clase Renderer_Punto.

    /*
     * Creado el 23 de mayo, 2012 por Hernán Nina Hanco
     *
     * Este trabajo es parte del proyecto CG1, que corresponde a la 
     * implementación de algoritmos de Dibujo de graficas.
     * 
     * Universidad Nacional de San Antonio Abad del Cusco
     * Carrera Profesional de Ingeniería Informática y de Sistemas
     * Asignatura: Computación Gráfica I
     */

    package geometrias.lineas;
    /*
     * Dibujo de líneas con pendiente -1<m<1
     * @author Hernan Nina Hanco 
     */

    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.media.opengl.*;

    public class Renderer_Linea implements GLEventListener {

        static final Logger logger = Logger.getLogger("BasicLoggingExample");
        protected GL2 gl;
        /*
         * Inicializar graficador OpenGL
         */

        @Override
        public void init(GLAutoDrawable gLDrawable) {
            logger.log(Level.INFO, "método - init");
            // Provee un objeto que enlaza las APIs del OpenGL
            // Que se encargara de realizar las instrucciones de dibujos 
            gl = gLDrawable.getGL().getGL2();

            // Color de fondo del GLCanvas
            gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            gl.glClear(GL2.GL_COLOR_BUFFER_BIT);

            // definir el color del pincel
            gl.glColor3f(1.0f, 0.0f, 0.0f);

        }
        /*
         * Método para actualizar el dibujo cuando,
         * se modifica el tamaño de la ventana.
         */

        @Override
        public void reshape(GLAutoDrawable glad, int x, int y, int width,
                int height) {
            logger.log(Level.INFO, "Reshape");
            // 7. Especificar el área de dibujo (frame) utilizamos coordenadas
            gl.glMatrixMode(GL2.GL_PROJECTION);
            gl.glLoadIdentity();
            gl.glOrtho(-300, 300, -300, 300, -1.0, 1.0);
            // Dibujar un Sistema de Referencia.
            
        }
        /*
         *  
         */

        @Override
        public void dispose(GLAutoDrawable glad) {
            // no implementado
        }

        /*
         * Inicializar y presentar el dibujo de OpenGL
         */
        @Override
        public void display(GLAutoDrawable drawable) {
            int x0, y0, xn, yn, dx, dy;
            // Establecer el tamaño y color del punto     
            gl.glPointSize(1);
            gl.glColor3f(0.0f, 0.0f, 1.0f);

            // Dibujo de Líneas de pendiente positiva y menor a 1 
            // utilizando diferentes métodos 
            // A) Dibujar una Línea según la ecuación punto pendiente
            lineaPuntoPendiente(50, 50, 290, 120);
            // B) Dibujar una Línea utilizando el algoritmo de línea DDA
            lineaDDA(50, 70, 290, 140);
            // C) Dibujar una Línea utilizando el algoritmo de línea de Bresenham
            lineaBresenham(50, 90, 290, 160);
            // D) Dibujar una Línea utilizando el algoritmo de OpenGL        
            lineaOpenGL(50, 110, 290, 180);
        }
        
        /*
         * Algoritmo DDA con pendiente -1<m<1
         */

        void lineaDDA(int x0, int y0, int xn, int yn) {
            int x;
            float m, y;
            // Calcular la pendiente
            m = (float) (yn - y0) / (xn - x0);
            x = x0;
            y = y0;
            // Tomar el intervalo del eje X y determinar Y    
            while (x < xn + 1) {
                //Dibujar un punto en la coordenada X, Y
                dibujarPunto(x, Math.round(y));
                /* Determinar el siguiente pixel */
                x++;
                y += m; // el incremento es la pendiente
            }
        }
        /*
         * Algoritmo para el dibujo de Línea con la ecuación 
         * punto pendiente con pendiente -1<m<1
         */

        void lineaPuntoPendiente(int x0, int y0, int xn, int yn) {
            int x;
            float m, b, y;
            // Calcular la pendiente y la constante b
            m = (float) (yn - y0) / (xn - x0);
            b = (float) (y0 - m * x0);

            x = x0;
            y = y0;
            // Tomar el intervalo del eje X y determinar Y    
            while (x < xn + 1) {
                //Dibujar un pixel en la posición X, Y
                dibujarPunto(x, Math.round(y));
                x++;
                y = m * x + b; /* Ecuación punto pendiente de la recta */
            }
        }

        /*
         * Algoritmo para el dibujo de Línea con el algoritmo de  
         * Bresenham con pendiente -1<m<1
         */

        public void lineaBresenham(int x0, int y0, int xn, int yn) {

            // Identificar los valores x0,y0
            int x = x0;
            int y = y0;
            // Calcular la constantes deltax, deltay, 2.deltay y 2deltay-2deltax
            int deltax = xn-x0;
            int deltay = yn-y0;
            int incrA = 2*deltay; // incremento si Pk es menor a 0 
            int incrB = 2 * (deltay - deltax);
            int pk = 2*deltay-deltax; // calcular p0
            // Tomar el intervalo del eje X y determinar Y    
            while (x < xn + 1) {
                dibujarPunto(x, y); /* Escribir en el framebuffer */
                /* Deteminar el siguiente pixel */
                x++; 
                if (pk < 0) {
                    pk += incrA;
                } else {
                    y++;
                    pk += incrB;
                }
            }
        }
        /*
         * Algoritmo para el dibujo de Línea con el algoritmo implementado  
         * por OpenGL considere la pendiente -1<m<1
         */

        void lineaOpenGL(int x0, int y0, int xn, int yn) {
            // Determinar el grosor de la línea
            gl.glLineWidth(1.0f);
            // Activar el estado de dibujo de líneas
            gl.glBegin(GL2.GL_LINES);
                // Establecer el punto inicial y final
                gl.glVertex2i(x0, y0);
                gl.glVertex2i(xn, yn);
            gl.glEnd();
        }
             /*
         * Dibujar un punto 
         */

        protected void dibujarPunto(int x, int y) {
            gl.glBegin(GL.GL_POINTS);
                gl.glVertex2i(x, y);
            gl.glEnd();
        }
    }

    Resultado de la aplicación, utilice la clase Ventana del Laboratorio 1, para mostrar los resultados.


    IV) Tarea

    1) Modifique el programa anterior para dibujar un sistema de coordenadas como se muestra en la Figura.


    2) Modificar el programa de la práctica donde se modifique los algoritmos de dibujo de línea para el dibujo de líneas con pendiente arbitraria.
    3) Modificar el programa de la práctica que considere el ingreso por parte del usuario, los extremos de una línea recta.
    4) Evalué el tiempo de ejecución de los algoritmos de dibujo de líneas, considere tabulación de datos y gráficas. (Ayuda: Tiempo en nanosegundo en java se obtiene con la sentencia): 
    long tiempo = System.nanoTime();

    V) Referencias

    • Donalf Hearn, M. Pauline Baker; Gráficas por Computadora con OpenGL; Pearson Prentice Hall; 3° edición; Madrid 2006.
    • Richard S. Jr., Michael Sweet; Programación en OpenGL una guía de referencia
    • Hosting del proyecto esta en: http://code.google.com/p/graficaporc/ 

    1-10 of 11