package math.fractals;

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;

public class Fractal25 extends JFrame{
	private static final long serialVersionUID = 8169105040941367402L;
	private static final int fw = 1000;
	private static final int fh = 1000;

	public static void main(String[] args) {
		SwingUtilities.invokeLater(() -> new Fractal25(new AtraktorLorenzaPanel()));
	}

	public Fractal25(JComponent comp){
		setLayout(null);
		setPreferredSize(new Dimension(fw, fh));
		setBounds((Toolkit.getDefaultToolkit().getScreenSize().width / 2)
				- (fw / 2),
				(Toolkit.getDefaultToolkit().getScreenSize().height / 2)
						- (fh / 2), fw, fh);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setTitle("Fraktal Julii");
		JPanel panel = (JPanel) comp;
		panel.setLocation((fw - panel.getWidth()) / 2,
				(fh - panel.getHeight()) / 2);
		add(panel);
		setVisible(true);
	}
}

class AtraktorLorenzaPanel extends JPanel{
	private static final long serialVersionUID = -5687462725803856608L;
	private double x0 = (Math.random() * 48.0 - 24.0) / 2.0;
	private double y0 = (Math.random() * 48.0 - 24.0) / 2.0;
	private double z0 = Math.random() * 24.0 / 2.0;
	private static final double ro = 10.0;
	private static final double r = 28.0;
	private static final double b = 8.0 / 3.0;
	private static final double h = 0.01;
	private final Ellipse2D.Double el;

	public AtraktorLorenzaPanel(){
		setBackground(Color.white);
		setPreferredSize(new Dimension(800, 800));
		setSize(800, 800);
		setBackground(Color.WHITE);
		el = new Ellipse2D.Double();
		el.height = 1.0;
		el.width = 1.0;
	}

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D)g;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		g2.setStroke(new BasicStroke(1));
		g2.setColor(Color.BLUE);
		g2.translate(200, 200);
		for(int i = 0; i < 8000; i++){
			el.x = x0 * 10 + 210;
			el.y = y0 * 10 + 210;
			g2.draw(el);
			double x1 = x0 + h * ro * (y0 - x0);
			double y1 = y0 + h * (x0 * (r - z0) - y0);
			double z1 = z0 + h * (x0 * y0 - b * z0);
			x0 = x1;
			y0 = y1;
			z0 = z1;
		}
	}
}
