miércoles, 28 de septiembre de 2016

Dibujar poligonos en java

Primero que nada al igual que el anterior post.

Una disculpa por no estar aquí desde hace mucho, últimamente ( desde hace ya dos años ) me encuentro trabajando de tiempo completo y bueno, deje a un lado esto del blog, entre otros proyectos personales. 

Bueno esto no sera una escusa para dejar de hacer lo que me gusta "Programar" es por ello que les traigo una entrada el cual sera una pequeña explicación de un proyecto echo en java para dibujar poligonos según sea la posición del puntero un punto en el dibujo.

El código aquí mostrado es meramente propio, así que si encuentran alguna manera de hacerlo mas practico, les pido dejen sus comentarios de como lo mejorarían. 

La idea a llegar es la siguiente:


Empieza el dibujo en blanco y al dar click en una parte del lienzo, es ahí donde comienza a pintar el poligono.









Bueno comencemos.

Creamos un proyecto al cual e llamado CreaPolygons.java

public class CreatePolygons extends JFrame implements MouseListener, 
                                                      MouseMotionListener, 
                                                      KeyListener {
/*
 * Declaramos las variables fijas alto y ancho para utilizarlas posteriormente en diferentes partes del  * proyecto
 */
 final int width = 600;
 final int height = 700;

/* El resto de variables que utilizaremos tales como valor x,y, xRelease, yRelease, posicion actual del punto agregado al poligono, numero de poligonos  creados*/

    int x = -1, 
         y = -1, 
         xR = 0,
         yR = 0,
         posicion = 0,
         poligonos = 0;
    boolean release = false, 
                  cambioPoligono = true,
                  ctr = false;
  /*la siguiente lista se ocupa para agregar en ella los poligonos que se han dibujado, se crea en base a una clase que se crea posteriormente*/
 List< ListaArreglo> poligono = new ArrayList<>();
/* el constructor el cual nos dará como resultado el marco sobre el cual estaremos dibujando nuestros poligonos*/
public CreatePolygons() {
        setTitle( "Dibujando poligonos" );
        addMouseMotionListener(this);
        addMouseListener(this);
        addKeyListener(this);
        setSize(width, height);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
/*El metodo paint se encarga de pintar los poligonos agregados anteriormente en la lista de poligonos que hemos creado y se va llenando conforme damos click sobre el lienzo*/
@Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.WHITE);
        g2.fillRect(0, 0, width, height);
        g2.setColor(Color.BLACK);
        if (poligono.size() > 0) {
            /* se recorre la lista poligono dentro de la cual contiene unas listas de tipo clase arreglos esta lista contiene la coordenadas de cada uno de nuestros puntos*/
            for (int i = 0; i < poligono.size(); i++) {
                for (int j = 0; j < poligono.get(i).getLista().size(); j++) {
                    Arreglos _p = poligono.get(i).getLista().get(j);
                    g2.drawPolygon(_p.getX(), _p.getY(), _p.getX().length);
                }

            }
        }
        if (release) {
            g2.drawLine(x, y, xR, yR);
        }
    }
/*debido a la herencia de la interface mouseListener es necesario agregar los metodos abstractos a la clase */

    @Override
    public void mouseClicked(MouseEvent e){}
    @Override
    public void mouseEntered(MouseEvent e){}
    @Override
    public void mouseReleased(MouseEvent arg0){}
    @Override
    public void mouseExited(MouseEvent e){}
/* sin embargo el metodo mousePressed es el que nos interesa es por ello que sobreescribiremos de este su contenido*/
    @Override
    public void mousePressed(MouseEvent e) {
        /*dependiendo el boton del mouse que se este presionando sera la acción que se ejecute, en este caso el boton 1 ( click izquierdo ) agrega un punto al poligono, el boton 2 ( presionando el scroll ) finaliza el poligono , presionando la tecla Ctrl + click con scroll del mouse, imprimirá en consola los puntos que forman al poligono, el boton 3 ( click derecho ) junto con la tecla Ctrl presionada mientras se da click  eliminara el ultimo punto de creado*/
        if (e.getButton() == 1) {
            /*si el valor de x < 0 ( es desir es el primer punto de la lista ) se asignan los valores y este punto sera nuestro punto de partida*/
            if (x < 0) {
                x = e.getX();
                y = e.getY();
            } else {
               /*creamos una instancia de la clase arreglos para poder agregarle los arreglos correspondientes que seran los primeros dos puntos de nuestra primera linea y consecuentes para ir dibujando */
                Arreglos _arr = new Arreglos();
                int[] ax = {x, e.getX()};
                int[] ay = {y, e.getY()};
/*reasignamos los valores a x, y  dandole los valores  actuales del mouse que tenemos en el lienzo*/
                x = e.getX();
                y = e.getY();
                _arr.setX(ax);
                _arr.setY(ay);
/* la bandera cambioPoligono nos indica si se pidio finalizar el poligono o se mantiene en la misma figura.*/
                if (!cambioPoligono) {
                    poligono.get(poligonos).getLista().add(_arr);
                } else {
                    List<Arreglos> l = new ArrayList<>();
                    l.add(_arr);
                    ListaArreglo la = new ListaArreglo();
                    la.setLista(l);
                    poligono.add(la);
                    cambioPoligono = false;
                }
/*al final de esta accion aumentamos en uno la posicion del punto que se va a generar*/
                posicion++;
            }
            release = true;
        } else if (e.getButton() == 2) {
/* si se esta presionando la tecla Ctrl se imprime en consola los valores de los poligonos que se estan pintando en el lienzo*/
            if( ctr ){
                for (int i = 0; i < poligono.size(); i++) {
                    for (int j = 0; j < poligono.get(i).getLista().size(); j++) {
                        Arreglos _ar = poligono.get( i ).getLista().get( j );
                        System.out.println( "Poligono: {" + i + "} : [" + _ar.getX()[ 0 ] + "," + _ar.getY()[ 0 ] + " --> " +  + _ar.getX()[ 1 ] + "," + _ar.getY()[ 1 ] + "]");
                    }
                }
                System.out.println();
            }else{
/*de lo contrario si no se tiene presionado la tecla Ctrl, se finaliza el poligono y se indica que se creara uno nuevo*/
                int[] px = { x, xR };
                int[] py = { y, yR };
                Arreglos _arr = new Arreglos();
                _arr.setX( px );
                _arr.setY( py );
                poligono.get( poligonos ).getLista().add( _arr );
                int[] nx = { xR ,poligono.get( poligonos ).getLista().get( 0 ).getX()[ 0 ] };
                int[] ny = { yR ,poligono.get( poligonos ).getLista().get( 0 ).getY()[ 0 ] };
                Arreglos _a = new Arreglos();
                _a.setX( nx );
                _a.setY( ny );
                poligono.get( poligonos ).getLista().add( _a );
/*es necesario resetear las variables para poder crear un poligono nuevo.*/
                cambioPoligono = true;
                poligonos++;
                posicion = 0;
                release = false;
                x = -1;
                y = -1;
            }
        } else if (e.getButton() == 3) {
/* Si se esta presionando la tecla Ctrl se recorre la lista que contiene a nuestras figuras, de esta manera se obtiene la ultima posicion guardada y se remueve de la lista.*/
            if( ctr ){
                if( posicion > 0 ){
                    posicion --;
                    x = poligono.get( poligonos ).getLista().get( posicion ).getX()[0];
                    y = poligono.get( poligonos ).getLista().get( posicion ).getY()[0];
                    poligono.get( poligonos ).getLista().remove( posicion );
                }else if( poligono.size() > 0 ){
                    poligono.remove( poligonos );
                    posicion = poligono.get( poligonos - 1).getLista().size() - 1;
                    poligono.get( poligonos - 1 ).getLista().remove( posicion );
                    poligonos -- ;
                }
                release = true;
            }
        }
    }
/*al igual que hace un momento es necesario agregar los metodos de la interface mouseMotionListener*/
    @Override
    public void mouseDragged(MouseEvent me){}
/*Mientras se esta moviendo el mouse se setean las variablees xRelease, yRelease y al final se repinta el lienzo*/
    @Override
    public void mouseMoved(MouseEvent me) {
        xR = me.getX();
        yR = me.getY();
        repaint();
    }
/* de igual forma los metodos de la interface KeyListener*/
    @Override
    public void keyTyped(KeyEvent ke){}
/* sobre escribimos el metodo keypressed para captar el momento en que se presiona la tecla Ctrl en ese momento se cambia el estatus de la variable ctr a verdadero,  se agrega la condision de que si se presiona la tecla Ctrl y la tecla N limpia las variables e inicia de ceros todo el proyecto de sierto modo crea un nuevo proyecto.*/
    @Override
    public void keyPressed(KeyEvent ke){
        if( ke.getKeyCode() == 17 ){
            ctr = true;
        }
        if( ctr && ke.getKeyCode() == 78 ){
            x = -1;
            y = -1;
            poligonos = 0;
            posicion = 0;
            poligono = new ArrayList<>();
            release = false;
        }
    }
/*El metodo keyReleased cambia el estatus de la variable ctr a falso*/
    @Override
    public void keyReleased(KeyEvent ke) {
        if( ke.getKeyCode() == 17 ){
            ctr = false;
        }
    }
/* dentro de la clase principal creamos las siguientes subclases Arreglos y ListaArreglo, las cuales nos serviran de apoyo para la correcta función del proyecto.*/
    class Arreglos {
        int[] x;
        int[] y;
        public int[] getX() {
            return x;
        }
        public void setX(int[] x) {
            this.x = x;
        }
        public int[] getY() {
            return y;
        }
        public void setY(int[] y) {
            this.y = y;
        }
    }
    class ListaArreglo {
        List<Arreglos> lista;
        public List<Arreglos> getLista() {
            return lista;
        }
        public void setLista(List<Arreglos> lista) {
            this.lista = lista;
        }
    }
/*al final creamos nuestro metodo principal*/
    public static void main(String[] args) {
        CreatePolygons p = new CreatePolygons();
    }
}



Y esto es todo, posdata: no olvides agregar las respectivas importaciones, quiero comentar que este proyecto lo realice en NetBeans, es por ello que no agregué las importaciones.

No olvides dejar tu comentario, y si te sirve el código, recomienda me...