The assignment due Wednesday March 25 will consist of two parts:
The first part of the assignment is mostly fun, and shouldn't be much of a challenge. Of course you can go to town with it if you'd like, and produce something really wild and interesting. I know I would. :-)
In the notes below, first I duplicate what we covered in class on Wednesday, showing the two simple examples of using the MISApplet class. Then I go over our discussion of how to scan-convert a triangle by breaking it up into two trapezoids.
(1) Extending the MISApplet class
The following applet, which we implemented in class, extends MISApplet.java:
import java.awt.*; public class test1 extends MISApplet { double t = 0; public void initFrame(double time) { t = 4 * time; } public void setPixel(int x, int y, int rgb[]) { x -= W / 2; y -= H / 2; double r = Math.sqrt(x * x + y * y) / W; rgb[0] = (int)(255 * (0.5 + 0.5 * Math.sin( 50 * r - t))); rgb[1] = (int)(255 * (0.5 + 0.5 * Math.sin( 75 * r - t))); rgb[2] = (int)(255 * (0.5 + 0.5 * Math.sin(100 * r - t))); } }As you can see if you launch it, it produces cool looking expanding rings of color. It also runs a little slowly, because there are so many floating point operations for each pixel. Clearly, we want to avoid lots of floating point operations per pixel, if we're going to do real-time rendering in Java applets.
The second applet we implemented in class tries harder to be efficient - doing only integer operations in the inner loop. I've added some comments, to make it easier for you to follow the code. Unlike the first applet, this one is interactive:
import java.awt.*; public class test2 extends MISApplet { int mx = 0, my = 0; int white = pack(255,255,255); int black = pack( 0, 0, 0); int gray = pack(128,128,128); int red = pack(255, 0, 0); boolean isMouseDown = false; int radius = 30; int myColor = pack(200, 0, 0); public void initialize() { mx = W / 2; my = H / 2; } public void computeImage(double time) { // PAINT A BLACK AND WHITE CHECKBOARD AS THE BACKGROUND PATTERN int i = 0; for (int y = 0 ; y < H ; y++) for (int x = 0 ; x < W ; x++) { int _i = x / 50; int _j = y / 50; pix[i++] = (_i + _j) % 2 == 0 ? black : white; } // DRAW THE MOVING SPOT for(int y = my - radius ; y < my + radius ; y++) for(int x = mx - radius ; x < mx + radius ; x++) { // LOOP THROUGH A SQUARE REGION, BUT ONLY DRAW THOSE // PIXELS THAT FALL INSIDE A CIRCULAR DISK int rr = (x - mx) * (x - mx) + (y - my) * (y - my); if (rr < radius * radius) { i = xy2i(x, y); if (i >= 0 && i < pix.length) { if (isMouseDown) { // OPACITY DROPS OFF WITH RADIUS int c = Math.max(0, 255 * rr / (radius * radius) - 128); // OPAQUE PIXELS JUST GET WRITTEN TO THE FRAME BUFFER if (c == 0) pix[i] = myColor; // TRANSLUCENT PIXELS NEED TO BE BLENDED IN else { int bg = pix[i]; int red = ilerp(c, 200, unpack(bg, 0)); int grn = ilerp(c, 0, unpack(bg, 1)); int blu = ilerp(c, 0, unpack(bg, 2)); pix[i] = pack(red, grn, blu); } } else pix[i] = gray; } } } } // TRACK WHERE THE USER DRAGS, AND IF MOUSE BUTTON IS PRESSED public boolean mouseDown(Event e, int x, int y) { isMouseDown = true; return true; } public boolean mouseUp(Event e, int x, int y) { isMouseDown = false; return true; } public boolean mouseDrag(Event e, int x, int y) { mx = x; my = y; return true; } // FIXED POINT VERSION OF LINEAR INTERPOLATION, WITH 256 AS UNITY int ilerp(int t, int a, int b) { return a + (t * (b - a) >> 8); } }You can launch this applet by clicking here. What I would like you to do is try your hand at making your own 2D applet this way. See if you can create interesting shapes, or even entire scenes. You can make it interactive or non-interactive, us you wish. Try different things, experiment, have fun.
(2) Scan converting a triangle
Notes coming soon - watch this space...