Today’s topics Java Upcoming Reading

advertisement
Today’s topics
Java
Recursion in Graphics
Writing a Class
Simple Animation
Upcoming
Simulation
Reading
Great Ideas, Chapters 5
CompSci 001
18.1
Using Recursion in Graphics


Recursion can be a powerful tool
Closely related to Fractals




Self-similarity
Keep zooming in: still looks the same
Can produce very interesting figures with very little
input
Serpinsky Gasket is just a lot of triangles

Define recursively
CompSci 001
18.2
Serpinsky Gasket

Start with triangle

Then put (1/2 size) triangles within triangle
CompSci 001
18.3
Serpinsky Gasket

Continue process with ¼ sized triangles, etc

Insight: use Serpinsky Gaskets instead of triangles
CompSci 001
18.4
Serpinsky
public class Serpinsky extends java.applet.Applet implements
ActionListener {
Graphics g;
Canvas c;
IntField iSlow;
Button b1, b2, b3, b4, b5, b6, b7, b8, b9;
Color col;
int x, y, slow;
public void init() {
c = new Canvas();
c.setSize(400, 400);
add(c);
g = c.getGraphics();
b1 = new Button("Start"); b2 = new Button("Triangle");
b3 = new Button("Gasket"); b4 = new Button("Red");
CompSci 001
18.5
Serpinsky.2
b5 = new Button("Green"); b6 = new Button("Blue");
b7 = new Button("Black"); b8 = new Button("White");
b9 = new Button("Slow");
iSlow = new IntField(10);
col = Color.blue;
slow = 0;
b1.addActionListener(this); b2.addActionListener(this);
b3.addActionListener(this); b4.addActionListener(this);
b5.addActionListener(this); b6.addActionListener(this);
b7.addActionListener(this); b8.addActionListener(this);
b9.addActionListener(this);
add(iSlow); add(b1); add(b2); add(b3); add(b4); add(b5);
add(b6); add(b7); add(b8); add(b9);
}
CompSci 001
18.6
Serpinsky.3
int mid(int a, int b) {
return (a + b)/2;
}
void triangle(int x1, int y1, int x2, int y2, int x3,
int y3) {
int k;
k = 0;
while ( k < slow)
k = k + 1; // code to slow down
g.drawLine(x1, y1, x2, y2);
g.drawLine(x2, y2, x3, y3);
g.drawLine(x3, y3, x1, y1);
}
CompSci 001
18.7
Serpinsky.4
void serpinsky(int x1, int y1, int x2, int y2, int x3, int y3) {
int size, limit=10;
size = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
if (size < limit)
return; // base case: do nothing! i.e.: halting case
triangle(x1, y1, x2, y2, x3, y3);
// recursive calls
serpinsky(x1, y1, mid(x1,x2), mid(y1,y2), mid(x1,x3),
mid(y1,y3));
serpinsky(x2, y2, mid(x2,x1), mid(y2,y1), mid(x2,x3),
mid(y2,y3));
serpinsky(x3, y3, mid(x3,x1), mid(y3,y1), mid(x3,x2),
mid(y3,y2));
}
CompSci 001
18.8
Serpinsky.5
public void actionPerformed(ActionEvent event) {
Object cause = event.getSource();
if (cause == b1) {
g.setColor(Color.white); // Color the whole canvas white
g.fillRect(0, 0, 400, 400);
g.setColor(Color.black);
g.drawString("Serpinsky Gasket", 20, 20);
}
if (cause == b2) {
g.setColor(col);
triangle(50, 310, 200, 70, 350, 310);
}
if (cause == b3) {
g.setColor(col);
serpinsky(50, 310, 200, 70, 350, 310);
}
CompSci 001
18.9
Serpinsky.6
if (cause == b4) {
col = Color.red;
}
if (cause == b5) {
col = Color.green;
}
if (cause == b6) {
col = Color.blue;
}
if (cause == b7) {
col = Color.black;
}
if (cause == b8) {
col = Color.white;
}
if (cause == b9) {
slow = iSlow.getInt();
}
}
}
CompSci 001
18.10
Serpinsky Details

Note feature to slow down drawing



Get betters sense of how recursive calls work
Also see how incredibly fast computer is…
Note new graphics method
void drawString(String s, int x, int y)

Review recursive features


What is done in the base case?
What would figure be like if we drew nothing except

In the base case?
CompSci 001
18.11
Writing a Class

Have been writing one class all along




Write class named Serp which actually draws the gasket





Our applet is always a class
Have used other classes such as TextFields
Rewrite Serpinsky applet
Class requires data (instance variables)
Class requires methods (functions)
Needs constructor (to initialize) (like init in applet)
Now that we have such a class, can create many instances
Use the new operator to accomplish this:
new Serp(x1, y1, x2, y2, x3, y3, g);
 Where we pass in the 3 vertices of the triangle
 and the Graphics object
CompSci 001
18.12
SerpClass
public class SerpClass extends java.applet.Applet implements
ActionListener {
Graphics g;
Canvas c;
Button b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11;
Color col;
int range = 70;
public void init() {
c = new Canvas();
c.setSize(400, 400);
add(c);
g = c.getGraphics();
b1 = new Button("Start"); b2 = new Button("NW");
b3 = new Button("NE"); b4 = new Button("SW");
b5 = new Button("SE"); b6 = new Button("CTR");
b7 = new Button("Red"); b8 = new Button("Green");
b9 = new Button("Blue"); b10 = new Button("Black");
CompSci 001
18.13
SerpClass.2
col = Color.black;
b1.addActionListener(this); b2.addActionListener(this);
b3.addActionListener(this); b4.addActionListener(this);
b5.addActionListener(this); b6.addActionListener(this);
b7.addActionListener(this); b8.addActionListener(this);
b9.addActionListener(this); b10.addActionListener(this);
b11.addActionListener(this);
add(b1); add(b2); add(b3); add(b4); add(b5);
add(b6); add(b7); add(b8); add(b9); add(b10); add(b11);
}
public void actionPerformed(ActionEvent event) {
Object cause = event.getSource();
if (cause == b1) {
g.setColor(Color.white); // Color the whole canvas white
g.fillRect(0, 0, 400, 400);
g.setColor(Color.black);
g.drawString("Serpinsky Gasket", 20, 20);
}
CompSci 001
18.14
SerpClass.3
if (cause == b2) { // NW
int dx = -range, dy = -range;
g.setColor(col);
new Serp(50+dx, 310+dy, 200+dx, 70+dy, 350+dx, 310+dy,
g);
}
if (cause == b3) { // NE
int dx = range, dy = -range;
g.setColor(col);
new Serp(50+dx, 310+dy, 200+dx, 70+dy, 350+dx, 310+dy,
g);
}
if (cause == b4) { // SW
int dx = -range, dy = range;
g.setColor(col);
new Serp(50+dx, 310+dy, 200+dx, 70+dy, 350+dx, 310+dy,
g);
}
CompSci 001
18.15
SerpClass.4
if (cause == b5) { // SE
int dx = range, dy = range;
g.setColor(col);
new Serp(50+dx, 310+dy, 200+dx, 70+dy, 350+dx, 310+dy, g);
}
if (cause == b6) { // CTR
g.setColor(col);
new Serp(50, 310, 200, 70, 350, 310, g);
}
if (cause == b7)
col = Color.red;
if (cause == b8)
col = Color.green;
if (cause == b9)
col = Color.blue;
if (cause == b10)
col = Color.black;
if (cause == b11)
col = Color.white;
}
CompSci 001
18.16
SerpClass.5
public class Serp {
Graphics g;
public Serp(int x1, int y1, int x2, int y2, int x3, int y3,
Graphics gg) {
g = gg;
serpinsky(x1, y1, x2, y2, x3, y3);
}
public int mid(int a, int b) {
return (a + b)/2;
}
public void triangle(int x1, int y1, int x2, int y2, int x3,
int y3) {
g.drawLine(x1, y1, x2, y2);
g.drawLine(x2, y2, x3, y3);
g.drawLine(x3, y3, x1, y1);
}
CompSci 001
18.17
SerpClass.6
public void serpinsky(int x1, int y1, int x2, int y2, int x3,
int y3) {
int size, limit=200;
size = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
if (size < limit) // base case
return;
// do nothing
triangle(x1, y1, x2, y2, x3, y3);
// recursive calls
serpinsky(x1, y1, mid(x1,x2), mid(y1,y2), mid(x1,x3),
mid(y1,y3));
serpinsky(x2, y2, mid(x2,x1), mid(y2,y1), mid(x2,x3),
mid(y2,y3));
serpinsky(x3, y3, mid(x3,x1), mid(y3,y1), mid(x3,x2),
mid(y3,y2));
}
}
}
CompSci 001
18.18
Simple Minded Animation

Simple Recipe
1.
2.
3.
4.
5.

Draw and Erase



Draw figure
Delay
Erases figure
Shift slightly
Repeat (step 1. , etc.)
Draw figure: is straight-forward
Erase: overdraw with background color (white)
Will demonstrate with Serpinsky Gasket
CompSci 001
18.19
Moving Serpinsky
public class SerpMove extends java.applet.Applet implements
ActionListener {
Graphics g;
Canvas c;
IntField iSlow;
Button b1, b2, b3, b4, b5, b6, b7, b8, b9;
Color col;
int slow = 1000000;
public void init() {
c = new Canvas();
c.setSize(400, 400);
add(c);
g = c.getGraphics();
b1 = new Button("Start"); b2 = new Button("Move");
b3 = new Button("Gasket"); b4 = new Button("Red");
b5 = new Button("Green"); b6 = new Button("Blue");
b7 = new Button("Black"); b8 = new Button("White");
CompSci 001
18.20
Moving Serpinsky.2
b9 = new Button("Slow");
iSlow = new IntField(10);
col = Color.blue;
b1.addActionListener(this); b2.addActionListener(this);
b3.addActionListener(this); b4.addActionListener(this);
b5.addActionListener(this); b6.addActionListener(this);
b7.addActionListener(this); b8.addActionListener(this);
b9.addActionListener(this);
add(iSlow); add(b1); add(b2); add(b3); add(b4); add(b5);
add(b6); add(b7); add(b8); add(b9);
}
public void delay() {
double sum = 0.0, x = 3.14159265;
int k = 0;
while (k < slow) {
sum = sum + 1.0/x;
k = k + 1;
}
}
CompSci 001
18.21
Moving Serpinsky.3
public void actionPerformed(ActionEvent event) {
Object cause = event.getSource();
if (cause == b1) {
g.setColor(Color.white); // Color the whole canvas white
g.fillRect(0, 0, 400, 400);
g.setColor(Color.black);
g.drawString("Serpinsky Gasket", 20, 20);
}

Interesting Part Follows

Actual Motion done here
CompSci 001
18.22
Moving Serpinsky.4
if (cause == b2) { // move
int k = 0, range = 100;
int dx = -range, dy = -range;
while (k < range) {
dx = dx + 2;
dy = dy + 2;
g.setColor(col);
new Serp(50+dx, 310+dy, 200+dx, 70+dy, 350+dx, 310+dy, g);
delay();
g.setColor(Color.white);
new Serp(50+dx, 310+dy, 200+dx, 70+dy, 350+dx, 310+dy, g);
g.setColor(col);
k = k + 1;
}
}
CompSci 001
18.23
Moving Serpinsky.5
if (cause == b3) {
g.setColor(col);
new Serp(50, 310, 200, 70, 350, 310, g);
}
if (cause == b4)
col = Color.red;
if (cause == b5)
col = Color.green;
if (cause == b6)
col = Color.blue;
if (cause == b7)
col = Color.black;
if (cause == b8)
col = Color.white;
if (cause == b9)
slow = iSlow.getInt();
}
}
CompSci 001
18.24
Simple Minded Animation


Did not show the Serp class which is unchanged
Quality of animation is poor: flicker, not smooth






Beats with monitor and outside lighting
Speed dependence on processor and load
Erases anything “below”
Fixing this is outside the scope of this class
Should do much in this class that we do outside
Could (should) add a number of methods
Let it handle the move, just pass new locations
void setLocation(int newX, int newY)
void glideTo(int newX, int newY)
 The former would jump to new location, the latter would
provide continuous motion

CompSci 001
18.25
Download