sexta-feira, 1 de novembro de 2013

Desenhando e estudando sobre gráficos em Java

Bom dia galera,

este é um post técnico.

O post de hoje é sobre um estudo sobre um tipo estrutura chamada fractal. Nesse link tem uma explicação legal sobre fractais : link .

Hoje vou postar um código que cria um fractal que fez parte da minha infância. Quer dizer , anos de estudo de programação + matemática para criar o glorioso símbolo da... Triforce! Ohhhhhh (8)



Percebam o padrão que acontece nessa estrutura, é um triângulo grande com um triângulo invertido dentro. Se aplicarmos esse padrão várias vezes, podemos criar infinitas triforces o que gera o nosso fractal.

Eu encontrei uma api MUITO interessante para desenho , usada nos cursos de ciências da computação de Princeton chamado StdDraw. Ele oferece uma api muito interessante para se desenhar no Java, sem precisar aprender sobre Swing , GUI etc. O único conhecimento necessário é um conhecimento básico de matemática e basicamente qualquer coisa pode ser feita. Eu resolvi fazer esse padrão de fractal com a linguagem de programação Java. O link para a API é: link da API de desenho . Para usar essa api é só copiar a classe para uma classe dentro do seu projeto e começar a utilizar.

O código a seguir gera a lendária Triforce de maneira recursiva. Teoricamente podemos gerar infinitas triforces dentro de triforces:

   public static class TrianglePoint
    {
        double x1;
        double y1;
        double x2;
        double y2;
        String type;

        public TrianglePoint(double x1, double y1, double x2, double y2, String type)
        {
            this.x1 = x1;
            this.x2 = x2;
            this.y1 = y1;
            this.y2 = y2;
            this.type = type;        }

        public double getX1()
        {            return x1;        }

        public void setX1(double x1)
        {            this.x1 = x1;        }

        public double getY1()
        {            return y1;        }

        public void setY1(double y1)
        {            this.y1 = y1;        }

        public double getX2()
        {            return x2;        }

        public void setX2(double x2)
        {            this.x2 = x2;        }

        public double getY2()
        {            return y2;        }

        public void setY2(double y2)
        {            this.y2 = y2;        }

        public String getType()
        {            return type;        }

        public void setType(String type)
        {
            this.type = type;
        }
     
        public double midPointX(){
             return ((x1+x2)/2);        }

        public double midPointY(){
            return ((y1+y2)/2);        }
     
    }

    static void recursionMethod(Map<String,TrianglePoint> trianglePointsList, int times){
     
        List<String> listTypes = new ArrayList<String>();
       
        listTypes.add("transversal");
        listTypes.add("horizontal");
        listTypes.add("vertical");
     
        if(times == 0){
            return;
        }
     
        for(String type : listTypes){
         
            StdDraw.line(trianglePointsList.get(type).getX1(), trianglePointsList.get(type).getY1(), trianglePointsList.get(type).getX2(),
                    trianglePointsList.get(type).getY2());
            try{
            Thread.sleep(500);
            } catch (Exception e){              }
            }
     
            TrianglePoint horizontal = trianglePointsList.get("horizontal");
            TrianglePoint transversal = trianglePointsList.get("transversal");
            TrianglePoint vertical = trianglePointsList.get("vertical");
     
            TrianglePoint transversalOld = new TrianglePoint(trianglePointsList.get("transversal").getX1(),
                                                          trianglePointsList.get("transversal").getY1(),
                                                          trianglePointsList.get("transversal").getX2(),
                                                          trianglePointsList.get("transversal").getY2(),
                                                          trianglePointsList.get("transversal").getType());
         
            TrianglePoint horizontalOld = new TrianglePoint(trianglePointsList.get("horizontal").getX1(),
                    trianglePointsList.get("horizontal").getY1(),
                    trianglePointsList.get("horizontal").getX2(),
                    trianglePointsList.get("horizontal").getY2(),
                    trianglePointsList.get("horizontal").getType());
         
            TrianglePoint verticalOld = new TrianglePoint(trianglePointsList.get("vertical").getX1(),
                    trianglePointsList.get("vertical").getY1(),
                    trianglePointsList.get("vertical").getX2(),
                    trianglePointsList.get("vertical").getY2(),
                    trianglePointsList.get("vertical").getType());
         

            horizontal.setX1(transversalOld.midPointX());
            horizontal.setY1(transversalOld.midPointY());
            horizontal.setX2(verticalOld.midPointX());
            horizontal.setY2(verticalOld.midPointY());

            vertical.setX1(horizontalOld.midPointX());
            vertical.setY1(horizontalOld.midPointY());
            vertical.setX2(transversalOld.midPointX());
            vertical.setY2(transversalOld.midPointY());
         
            transversal.setX1(verticalOld.midPointX());
            transversal.setY1(verticalOld.midPointY());
            transversal.setX2(horizontalOld.midPointX());
            transversal.setY2(horizontalOld.midPointY());
     
        recursionMethod(trianglePointsList, times-1);
     
    }

    public static void main(String[] args)
    {

        Map<String,TrianglePoint> mapTriangle  = new HashMap<String,TrianglePoint>();
        mapTriangle.put("transversal", new TrianglePoint(0.0, 0.0, 0.5, 1.0,"transversal"));
        mapTriangle.put("horizontal", new TrianglePoint(0.0, 0.0, 1.0, 0.0,"horizontal"));
        mapTriangle.put("vertical", new TrianglePoint(1.0, 0.0, 0.5, 1.0,"vertical"));
     
        recursionMethod(mapTriangle, 2);

        System.out.println("triforce complete ");
    }

Esse código gera a seguinte saída:



Agora modificando a chamada principal do método recursivo para chamar 7 vezes:


        recursionMethod(mapTriangle, 8);

A seguinte imagem é gerada:


Bom, espero que tenham se divertido um pouco com esse estudo de fractais e API de Princeton. O desafio agora é fazer formas mais complexas de fractais como por exemplo esse link : link .

Abraços até a próxima.