Curva de Koch

Alguém poderia dar uma ajuda ou algumas dicas.

Preciso implementar um código que imprima uma curva de koch, como essa:

image

Fiz uma classe mãe que se chama Image, segue o código:

import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;

public class Image {

	private int width, height;
	private BufferedImage image;
	private Graphics graphics;

	private Color color;
	private Color bgColor;

	public Image(int w, int h, int r, int g, int b){

		setup(w, h, r, g, b);
	}

	public Image(int w, int h){

		setup(w, h, 0, 0, 0);
	}

	private void setup(int w, int h, int r, int g, int b){

		image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
		width = image.getWidth();
		height = image.getHeight();
		graphics = image.createGraphics();
		
		setBgColor(new Color(limit(r), limit(g), limit(b)));
		setColor(Color.WHITE);
		clear();
	}

	private int limit(int value){

		return value < 0 ? 0 : (value > 255 ? 255 : value);
	}

	public void setBgColor(Color c){

		bgColor = c;
	}

	public void setBgColor(int r, int g, int b){

		setBgColor(new Color(limit(r), limit(g), limit(b)));
	}

	public void setColor(Color c){

		color = c;
	}

	public void setColor(int r, int g, int b){

		setColor(new Color(limit(r), limit(g), limit(b)));
	}

	public void clear(){

		graphics.setColor(bgColor);
		graphics.fillRect(0, 0, width, height);
	}

	public void setPixel(int x, int y){
			
		if(x >= 0 && y >= 0 && x < width && y < height){
			
			image.setRGB(x, y, color.getRGB());
		}
	}

	public int getPixel(int x, int y){

		return image.getRGB(x, y); 
	}

	public void drawLine(int x1, int y1, int x2, int y2){

		graphics.setColor(color);
		graphics.drawLine(x1, y1, x2, y2);
	}

	public void save(String fileName){

		try{

			ImageIO.write(image, "png", new File(fileName));
		}
		catch(IOException e){
	
			System.out.println("Unable to save image...");
			e.printStackTrace();
		}
	}
}

Tenho outra classe que converte o arquivo txt em imagem e ela imprime uma paisagem sem nada, da uma olhada:

image

Agora preciso implementar uma classe filha da curva de koch, porém não sei bem como fazer isso.

Que bacana, posta essa classe e o arquivo .txt, fiquei interessado.

Sobre a curva de Koch, tenho um exemplo baseado no código do livro Computação Gráfica para Programadores Java:
livro

Exemplo:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class KochFrame extends JFrame {

    class KochPanel extends JPanel {
        public float x, y;
        double dir;
        int midX, midY, level = 1;

        KochPanel() {
            addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent evt) {
                    level++; // Cada clique do mouse aumenta o nível em 1
                    repaint();
                }
            });
        }

        public void drawKoch(Graphics g, double len, int n) {
            if (n == 0) {
                double dirRad, xInc, yInc;
                dirRad = dir * Math.PI / 180;
                xInc = len * Math.cos(dirRad); // incrementa x
                yInc = len * Math.sin(dirRad); // incrementa y
                float x1 = x + (float) xInc, y1 = y + (float) yInc;
                g.setColor(Color.GREEN);
                g.drawLine(iX(x), iY(y), iX(x1), iY(y1));
                x = x1;
                y = y1;
            } else {
                drawKoch(g, len /= 3, --n);
                dir += 60;
                drawKoch(g, len, n);
                dir -= 120;
                drawKoch(g, len, n);
                dir += 60;
                drawKoch(g, len, n);
            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            Dimension d = getSize();
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, d.width, d.height);
            int maxX = d.width - 1, maxY = d.height - 1, length = 3 * maxX / 4;
            midX = maxX / 2;
            midY = maxY / 2;
            x = -length / 2; // ponto inicial
            y = 0;
            dir = 0;
            drawKoch(g, length, level);
        }

        int iX(float x) {
            return Math.round(midX + x);
        }

        int iY(float y) {
            return Math.round(midY - y);
        }
    }

    public static void main(String[] args) {
        KochFrame frame = new KochFrame();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    KochFrame() {
        super("Curva de Koch. Click com o mouse para aumentar o nível");
        setMinimumSize(new Dimension(600, 500));
        setResizable(false);
        add(BorderLayout.CENTER, new KochPanel());
    }
}

Código rodando:

Nenhum clique:
koch-1

1 clique:
koch-2

2 cliques:
koch-3

3 cliques:
koch-4

2 curtidas

kkk estou adorando fazer esse programa, mas tá dando bastante trabalho, já tô com a cabeça fervendo.

Sobre o método da função que gera aquela imagem eu usei essa aqui:

public class ImageTest {

	public static void drawScene(String fileName){

		int w = 512;
		int h = 512;
		Image img = new Image(w, h);
		img.setBgColor(0, 0, 0);
		img.clear();

		for(int i = 0; i < 15000; i++){

			int x = (int)(Math.random() * w);
			int y = (int)(Math.random() * h / 2);

			int r = 255;
			int g = (int)(64 + y/2 + Math.random() * 64); 
			int b = 255 - g;
			
			img.setColor(r, g, b);
			img.setPixel(x, y);
		}

		for(double d = 1; d <= 20; d++){

			int l = 1000;
			int f = 1;

			int x1 = (int)(w/2 - l/(f + d) * 5);
			int x2 = (int)(w/2 + l/(f + d) * 5);
			int y = (int)(h/2.5 + l/(f + d));

			img.setColor(0, 255, 128);
			img.drawLine(x1, y, x2, y);
		}

		for(double d = -1; d <= 1; d += 0.05){

			int l = 1000;
			int f = 1;

			int y1 = (int)(h/2.5 + l/(f + 1));
			int y2 = (int)(h/2.5 + l/(f + 20));

			int x1 = (int) (w/2 + l/(f + 1) * d * 5);
			int x2 = (int) (w/2 + l/(f + 20) * d * 5);

			img.setColor(0, 128, 255);
			img.drawLine(x1, y1, x2, y2);
			
		}

		img.save(fileName);
	}

	public static void main(String [] args){

		drawScene(args.length > 0 ? args[0] : "out.png");
	}
}

Já a classe que lê um arquivo txt e gera um arquivo PNG com os métodos da curva e preenchimento, eu estou fazendo ainda, então está em processo de execução, ela tá assim:

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;


public class ImageTest {

 
public static void ImagConfig(String [] args) {
int x1, y1, x2, y2;
Image img = new Image(int w, int h, int r, int g, int b);
Image img2 = new Image(int w, int h);
img.setColor(r, g, b);
img.setPixel(x, y);
img.drawLine(x1,y1,x2,y2);


public static void Koch_Curve(int l,double x1,double y1,double x2,double y2){           

//Fazer


}


public static void Region_Fill(int x,int y) {


//Fazer

}

 

public static void usaConfig(String fileName) {
String informacao = fileName.split(" ");
int[] guarda = new int [Informacao.length];


for(int i =0; i < Informacao.length;i++) {
guarda[i] = Integer.parseInt(Informacao[i]);//Converter String para int.

}
Image img = new Image(guarda[0],guarda[1],guarda[2],guarda[3],guarda[4]);
}

public static void LerArquivo(String[] args) throws IOException {
File file = new File(args[0]);
Scanner sc = new Scanner (System.in);

try {
    sc = new Scanner(file);
    usaConfig(sc.nextLine());
    while (sc.hasNextLine()) {
        }
}
    catch (IOException e) {
    System.out.println("Error: ");
}
  finally {
   if (sc != null) {
   sc.close();
      }
}

sc.close();
img.save(args[1]);

}

 

public static void main(String [] args){

usaConfig(args.length > 0 ? args[0] : "out.png");

}

}

A classe da curva e preenchimento, estou terminando o preenchimento, a curva já terminei, mas tenho que revisar os cálculos depois. Da uma olhada:

import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;

 
public class CurvaPreenchimento extends Image {
//Construtores da classe CurvaPreenchimento. 
public CurvaPreenchimento(int w, int h, int r, int g, int b) {
super(w,h,r,g,b);
}

public CurvaPreenchimento(int w, int h) {
super(w,h);
}

//Coordenadas iniciais
double cos60 = Math.cos(3.1415927/3.);
double sen60 = Math.sin(3.1415927/3.);


public void Koch(int l,double Px,double Py,double Qx,double Qy){
//dAB = √(x2-x1)^2 + (y2-y1) 
double m = Math.pow(Qx,2) - Math.pow(Px,2); 
double n = Math.pow(Qy,2) - Math.pow(Py,2); 
double resultado = Math.sqrt(m+n); 
double c = Math.round(resultado); 

//Caso o limite seja menor que o comprimento.
if ( l < c ) super.drawLine( (int)Px, (int)Py, (int)Qx, (int)Qy );

else{

         l = l - 1;

         double Ax = Px + (Qx-Px)/3.;//Ponto A, no eixo x e y, sendo 1/3.
         double Ay = Py + (Qy-Py)/3.;
         double Cx = Qx - (Qx-Px)/3.;//Ponto C, no eixo x e y, sendo 2/3.
         double Cy = Qy - (Qy-Py)/3.;
         double Bx = Ax + cos60*(Cx-Ax) + sen60*(Cy-Ay);// +: vira o desenho 60 graus no sentido horário.
         double By = Ay - sen60*(Cx-Ax) + cos60*(Cy-Ay); //-: vira o desenho 60 graus no sentido anti-horário.               

         Koch(l, Px, Py, Ax, Ay );//Comprimento PA
         Koch(l, Ax, Ay, Bx, By );//Comprimento AB
         Koch(l, Bx, By, Cx, Cy );//Comprimento BC
         Koch(l, Cx, Cy, Qx, Qy );//Comprimento CQ

       }

    }
	
public void Preenchimento(int x,int y) {
getPixel(x,y); 
setPixel(x,y); 
	
		
	}

  }

Estou nesse preenchimento agora, seguindo isso:

image
image

Tem alguma dica ? kkkk

Poderia me dar uma ajudinha no meu código ?