HW13 - james-bern/CS136 GitHub Wiki

image

The final project is effectively an open-ended Homework.

  • You can use Cow (✨ make sure to update it before you start) or any of the past homework, but you do not have to.
  • You must get permission beforehand if you want to use a language other than Java.
  • You must get permission beforehand if you want to use any external code other than past homeworks and Cow.java.
  • You must get permission beforehand if you want to work with a partner.
    • Note: Your project will have to be twice as good because there are two of you. 🙂👍

You may do your final project on whatever you like, provided you can answer the following questions.

  1. What is the title of my project?
  2. What data structures will I use? Note: Arrays count.
  3. What is the game/app that I am proposing? Who or what lives in it? What does it do? How does it feel?
  4. Will the viewer/player interact with my project? How so?
  5. Does Jim or a Lead TA think my project is doable? What is my fallback plan if my project ends up being harder/more time-consuming than I expect? What extensions can I do if my project ends up being easier/less time-consuming than I expect?
  6. What is the very first thing I will implement? (Drawing "the data" is usually a good first step.)

Here is a great example:

  1. Woo!-doku
  2. 2D array of ints to represent the board. (int[][] board = new int[9][9];)
  3. A colorful sudoku board, that does a happy dance when you solve it.
  4. Click to select cells. Type numbers on the keyboard to fill in numbers.
  5. Yes! And you can write a sudoku solver or automatic board generation if you have extra time!
  6. Store a board I found on the internet as a 2D array (-1's for empty cells) and draw it to the Terminal using System.out.println.

Examples

Mouse in Rectangle

Here we demonstrate testing whether the mouse is inside a rectangle.

👀
class HW13 extends Cow {
	public static void main(String[] arguments) {

		double left = 1.0;
		double bottom = 2.0;
		double right = 4.0;
		double top = 7.0;

		canvasConfig(0.0, 0.0, 8.0, 8.0);
		while (beginFrame()) {
			boolean insideX = (left < mouseX) && (mouseX < right);
			boolean insideY = (bottom < mouseY) && (mouseY < top);
			boolean inside = insideX && insideY;

			Color color;
			if (inside) {
				color = RED;
			} else {
				color = GREEN;
			}

			drawRectangle(left, bottom, right, top, color);
		}

	}
}
image

Mouse in Grid

Here we draw a grid and highlight the cell that the mouse is inside of.

Because the grid is an integer grid, we can find the lower left corner of the current cell by casting the x and y coordinates of the mouse's position to int's. The upper right corner is the lower left corner plus $(1, 1)$.

👀
class HW13 extends Cow {
	public static void main(String[] arguments) {

		// N x N grid
		int N = 16;

		canvasConfig(0, 0, N, N);
		while (beginFrame()) {
			// highlight square
			int x = (int) mouseX;
			int y = (int) mouseY;
			drawRectangle(x, y, x + 1, y + 1, YELLOW);

			// draw grid
			for (int i = 0; i <= N; ++i) {
				drawLine(0, i, N, i, BLACK);
				drawLine(i, 0, i, N, BLACK);
			}
		}

	}
}

Projectile Motion

Here we simulate the physics of a cannonball.

If the position of the ball is $\mathbf{p} = (p_x, p_y)^T$, the velocity is $\mathbf{v} = (v_x, v_y)^T$, and the acceleration is $\mathbf{a} = (0, -1)^T$, then the explicit euler update rule with timestep $h$ is

$$\mathbf{p}_{k+1} = \mathbf{p}_k + h * \mathbf{v}_k$$

$$\mathbf{v}_{k+1} = \mathbf{v}_k + h * \mathbf{a}_k$$

Note: If we consider the state to be $\mathbf{s} = (\mathbf{p}, \mathbf{v})^T$, then the update rule is just $\mathbf{s}_{k+1} = \mathbf{s}_k + h * \left(\frac{d\mathbf{s}}{dt}\right)_k$

👀
class HW13 extends Cow {
	public static void main(String[] arguments) {

		double p_x = 0.0; // position
		double p_y = 0.0;

		double v_x = 2.0; // velocity
		double v_y = 4.0;

		double a_x = 0.0; // acceleration
		double a_y = -1.0;

		double h = 0.1;  // timestep ("delta t")

		canvasConfig(0, 0, 16, 16);
		while (beginFrame()) {
			// explicit euler update
			v_x += h * a_x; // v += h * a;
			v_y += h * a_y;

			p_x += h * v_x; // p += h * v;
			p_y += h * v_y;

			drawCircle(p_x, p_y, 0.4, BLACK);
		}

	}
}

Color Gradient

Here we store the color of each cell in the $N\times N$ grid. In setup(), we map the index of each cell to a double between $0.0$ and $1.0$, and then use the Vector3 static method colorRainbowSwirl to turn that double into a color.

👀
class HW13 extends Cow {
	public static void main(String[] arguments) {

		// N x N grid
		int N = 8;

		Color canvas[][] = new Color[N][N];
		for (int i = 0; i < N; ++i) {
			for (int j = 0; j < N; ++j) {
				// NOTE: We have to cast the numerator to a double,
				//       otherwise an int divided by an int is an int!
				double t = ((double) (N * j + i)) / (N * N);
				canvas[i][j] = colorRainbowSwirl(t);
			}
		}

		canvasConfig(0, 0, N, N);
		while (beginFrame()) {
			for (int i = 0; i < N; ++i) {
				for (int j = 0; j < N; ++j) {
					drawRectangle(i, j, i + 1, j + 1, canvas[i][j]);
				}
			}
		}

	}
}

MS Paint Pencil Tool

👀
class HW13 extends Cow {
	public static void main(String[] arguments) {

		// N x N
		int N = 16;
		Color image[][] = new Color[N][N];
		for (int i = 0; i < N; ++i) {
			for (int j = 0; j < N; ++j) {
				image[i][j] = WHITE;
			}
		}

		canvasConfig(0, 0, N, N);
		while (beginFrame()) {
			if (mouseHeld) { 
				// convert mouse coordinates (double's)
				// into grid cell coordinates (int')
				int i = (int) mouseX;
				int j = (int) mouseY;
				image[i][j] = BLACK;
			}

			// drawing the grid
			for (int i = 0; i < N; ++i) {
				for (int j = 0; j < N; ++j) {
					drawRectangle(i, j, i + 1, j + 1, image[i][j]);
				}
			}
		}

	}
}
⚠️ **GitHub.com Fallback** ⚠️