Fractal Recursion Assignment

From Knowledge Kitchen
Jump to navigation Jump to search


Assignment

Choose one of the two fractal generating programs below and document it thoroughly, explaining how it works.

Requirements

Javadoc comments

Documentation must include full Javadoc comments, including:

  • the author tag should indicate "@author Foo Barstein, with comments by Bar Foostein (bf1234)". Replace "Bar Foostein" with your own name, and replace "bf1234" with your own NYU Net ID.
  • a description of the the entire program, and complete descriptions of all instance and class variables and methods.
  • for instance or class variables, be sure to explain how that variable is used throughout the rest of the program.
  • for each method, be sure to include a plain description of the method's purpose, and a detailed description of the process by which achieves that purpose.
  • for each method, also include a plain description of any parameters that the method accepts as well as a description of its return value, if any.

Additional comments

  • add a comment above any while or for loops describing the high-level purpose of the loop
  • add a comment above any recursive elements describing the high-level purpose of the recursion.
  • indicate any flags and state their purpose.
  • for any variable that is incremented or decremented, explain why.
  • for any method calls, please explain the purpose of the method call and any arguments passed to the method.
  • if the program inherits from another class, be sure to point out in comments any parent class methods or data fields that the code references.
    • also, be sure to point out any overridden methods

Program 1 - Fractal Tree

package edu.nyu.cs.fb1258.recursion_examples.assignment;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;

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

public class FractalTree extends JPanel {
    public Graphics2D g1;
    public static final int maxAngle = 360;
    public static final int startX = 600;
    public static final int startY = 800;
    public static final int numOfRecursions = 9;
    public static final int startAngle = 0;
    public static final double treeSize = 2;
    public static final int Detail = 3;
    public static final int randFact = 30;
    public static final int[] constFact = {-60, 05, -50, 45};
     
    public static int[] red =   {0, 0, 0, 0, 7, 15, 23, 31, 39, 47, 55, 43};
    public static int[] green = {171, 159, 147, 135, 123, 111, 99, 87, 75, 63, 51, 43};
    public static int[] blue =  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};   
     
    public static double degToRad(int deg) {
        return deg * Math.PI / 180;
    }
     
    public static void drawFractal(Graphics2D g1, int x, int y, int n, int angle) {
        if (n == Detail) return;
        int len = (int) Math.round(Math.pow(treeSize, n - 1));
         
        int xn1 = (int) Math.round(x - (2 * len * Math.sin(degToRad(angle))));
        int yn1 = (int) Math.round(y - (2 * len * Math.cos(degToRad(angle))));
        int mid1x = (x + xn1) / 2;
        int mid1y = (y + yn1) / 2;
        int mid2x = (mid1x + xn1) / 2;
        int mid2y = (mid1y + yn1) / 2;
        int mid3x = (x + mid1x) / 2;
        int mid3y = (y + mid1y) / 2;
        int mid4x = (mid3x + mid1x) / 2;
        int mid4y = (mid3y + mid1y) / 2;
         
        java.util.Random r = new java.util.Random();
        drawFractal(g1, mid1x, mid1y, n - 1, (angle + r.nextInt(randFact) + constFact[0]) % maxAngle);
        drawFractal(g1, mid2x, mid2y, n - 1, (angle + r.nextInt(randFact) + constFact[1]) % maxAngle);
        drawFractal(g1, mid3x, mid3y, n - 1, (angle + r.nextInt(randFact) + constFact[2]) % maxAngle);
        drawFractal(g1, mid4x, mid4y, n - 1, (angle + r.nextInt(randFact) + constFact[3]) % maxAngle);
         
        Color c = new Color(red[(r.nextInt() % 3) + n], green[(r.nextInt() % 3) + n], blue[(r.nextInt() % 3) + n]);
        g1.setColor(c);
        Line2D L1 = new Line2D.Double(x, y, xn1, yn1);
        g1.draw(L1);
        return;
    }
     
    public void paint(final Graphics g) {
        g1 = (Graphics2D) g;
        drawFractal(g1, startX, startY, numOfRecursions, startAngle);
    }
     
    public static void main(String args[]) {
        JFrame FF = new JFrame("Drawing a recursive tree");
        FF.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        FractalTree F = new FractalTree();
        FF.setBackground(Color.BLACK);
        FF.add(F);
        FF.pack();
        FF.setVisible(true);
        FF.setSize(1200, 1000);
    }
}

Program 2 - Mandelbrot Set

package edu.nyu.cs.fb1258.recursion_examples.assignment;

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public final class Mandel2 extends Applet implements MouseListener {
	private int max = 64;
	private Color[] colors = new Color[48];
	private double viewX = 0.0;
	private double viewY = 0.0;
	private double zoom = 1.0;
	private int mouseX;
	private int mouseY;

	public void init() {
		this.addMouseListener(this);
		for (int i = 0; i < colors.length; i++) {
			int c = 2 * i * 256 / colors.length;
			if (c > 255)
				c = 511 - c;
			this.colors[i] = new Color(c, c, c);
		}
		this.add(new Label("Drag a box around any area to zoom in"));		
	}

	public void paint(Graphics g) {
		this.setSize(new Dimension(600,400));
		Dimension size = getSize();
		for (int y = 0; y < size.height; y++) {
			for (int x = 0; x < size.width; x++) {
				double r = zoom / Math.min(size.width, size.height);
				double dx = 2.5 * (x * r + this.viewX) - 2.0;
				double dy = 1.25 - 2.5 * (y * r + this.viewY);
				int value = this.mandel(dx, dy);
				g.setColor(this.colors[value % this.colors.length]);
				g.drawLine(x, y, x, y);
			}
		}
	}

	public void update(Graphics g) {
		this.paint(g);
	}

	private int mandel(double px, double py) {
		double zx = 0.0, zy = 0.0;
		double zx2 = 0.0, zy2 = 0.0;
		int value = 0;
		while (value < this.max && zx2 + zy2 < 4.0) {
			zy = 2.0 * zx * zy + py;
			zx = zx2 - zy2 + px;
			zx2 = zx * zx;
			zy2 = zy * zy;
			value++;
		}
		return value == this.max ? 0 : value;
	}

	public void mousePressed(MouseEvent e) {
		this.mouseX = e.getX();
		this.mouseY = e.getY();
	}

	public void mouseReleased(MouseEvent e) {
		int x = e.getX();
		int y = e.getY();
		if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
			if (x != mouseX && y != mouseY) {
				int w = getSize().width;
				int h = getSize().height;
				this.viewX += this.zoom * Math.min(x, this.mouseX) / Math.min(w, h);
				this.viewY += this.zoom * Math.min(y, this.mouseY) / Math.min(w, h);
				this.zoom *= Math.max((double)Math.abs(x - this.mouseX) / w, (double)Math.abs(y - this.mouseY) / h);
			}
		}
		else if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) {
			this.max += max / 4;
		}
		else {
			this.max = 64;
			this.viewX = this.viewY = 0.0;
			this.zoom = 1.0;
		}
		this.repaint();
	}

	public void mouseClicked(MouseEvent e) {}
	public void mouseEntered(MouseEvent e) {}
	public void mouseExited(MouseEvent e) {}
}