© 2000-2003 A-Square, Inc.
This code is used in Exercise 5c. It includes the code for the Polygons universe as well as for the class EndPoint
Note the three main sections of a Rart universe:
Section 1 Identifying the universe
Section 2 What the universe does
Section 3 uParameters as used in the universe
>
/*
* @Polygons 1.2 010410
*
* © A-Square, Inc. 1996-2000
* 1648 Waters Edge Lane, Reston Virginia, 20190, USA
*/
import java.awt.*;
import rartbase.*;
/**
* Polygons universe
*
* Description: Displays a window with polygones whose coners wander across
* the screen. When the coners rech the border, they bounce off in random
* directions. There are a number of lines on the screen at one time and
* they change color as they progress.
*
* @author Jan Aminoff, December 2000
* This version is a simple adaptation of the original Lines universe.
* It is used as Example 5c in the Introduction to Java tutorial.
*
* Version 1.2 added the parameter to select background color
* analogus to what is done in Lines.
*/
public final class Polygons extends Universe {
// Section 1 Identifying the Universe
// ------------------------------------------------------------------------
public String getName(){ // Name
return("Polygons");} // Name of the universe.
public String getDescription(){
return(sd);}
private String sd= // Description
" In the Polygons universe the corners go straight, "+
"stepped in discrete steps until they bounce randomly "+
"against the edge of the window. Lines join the corners "+
"points for each step and the resulting patterns can be "+
"quite beautiful. ";
public String getRartist(){
return("Jan Aminoff 2000");} // Name of Rartist.
// end of Section 1
// Section 2 What the universe does
// -----------------------------------------------------------------------
private static int nn_max=600; // Maximum number of corners all polygons
private static int nc_max=6; // Maximum corners for one polygon
// The endpoints of the lines are saved in the following point array
private Point corners[] = new Point[nn_max];
// The EndPoints are the ones moving generating new lines as they move
private EndPoint corner[] = new EndPoint[nc_max]; // corners for one poly.
private int mp; // current index to polygon, j.
private int mc; // current index to corner of polygon, i.
private boolean resetScreen=false; // Flag to reset the screen as needed.
private Debug dB; // Not used but here if needed. See init.
public void init(){
/*
// Following establishes a pattern for setting and use of Debug.
// Debug is not used in this release of the Polygons universe.
dB=new Debug();
int dblevel=2
dB.setLevel(dblevel);
dB.dbg(1,"Debug Level now set to "+dblevel");
*/
setParams();
reset();
}
/**
* reset is used in init and also in manageChange when uParameters speed
* (with index VIEWSIZE), number (with index NUMBER), or ncorners (with
* index PARA5) have changed.
*/
private void reset(){
vv = speed.getCur(); // current maximum speed
nc = ncorners.getCur(); // current number of polygon corners
np = number.getCur(); // current number of polygons
// Note: nc * np < 600
// xm and ym are available from universe
for (int i=0; i<nc; i++){
corner[i] = new EndPoint(xm,ym,vv); // Set new Corners
}
mc=0; // index to current corner
mp=0; // index to current polygon
// reset the arrays of points
for (int j = 0; j<np; j++)
for (int i = 0; i<nc; i++)
corners[j*nc+i] = new Point(0,0);
// The following deals with the new ability to select color
// combinations as introduced in Ex5b of Intro to Java
cc=colorcomb.getCur();
if (cc==0) {
colorlines = false;
lineColor = Color.black;
background = Color.white;
}else if (cc==1){
colorlines = false;
lineColor = Color.white;
background = Color.black;
}else{
colorlines = true;
background = colors[cc-2];
}
// end of changing background addition
resetScreen=true;
} //end of reset
public void cycle (Graphics g){
if (resetScreen){
g.setPaintMode();
g.setColor(background);
g.fillRect(0,0,xm,ym);
resetScreen = false;
}
// Save corner points in point array
for (int i=0; i<nc; i++)
corners[mp*nc+i]=new Point(corner[i]);
//Update position of the corners
for (int i=0; i<nc; i++)
corner[i].move();
// Step index to point array
mp= (mp+1) % np;
// If we have been there, erase the former polygon
if ((corners[mp*nc].x!=0)&& (corners[mp*nc].y!=0)){
g.setColor(background);
drawPolygons(g,corners, mp, nc);
}
if (colorlines) {
// Step line color
hue++;
lineColor =
Color.getHSBColor((float)(hue/ 360.0),(float)1.0,(float)1.0);
hue = hue % 359; // keep going around the color wheel.
}
// Draw lines in color betwen the corners of the polygon
g.setColor(lineColor);
drawPolygons(g,corner, 0, nc);
} // end of cycle
private static void drawPolygons
( Graphics g, Point[] corners, int mp, int nc){
int xs[] = new int[nc];
int ys[] = new int[nc];
for (int i=0; i<nc; i++){
xs[i]= corners [mp*nc+i].x;
ys[i]= corners [mp*nc+i].y;
}
g.drawPolygon(xs,ys,nc);
}
// Color stuff
// Color stuff
/* In the enhancement introduced as Ex5b there are three variations of
* the Lines universe: Black lines on white, white lines on black, and
* lineColor stepped through 256 colors on a selectable background.
* The third version is distingushed by the boolean colorlines being true.
* The first two versions are distinguised by colorlines being false and
* the boolean blackonwhite being either true or false.
*
* Default is colorlines being true.
*/
private int cc=2; //Default choice of linecolor varying on black
private boolean colorlines=true;
private boolean blackonwhite;
// Following prescribed by Universe as released in RDK 1.0 beta
public Color getBackground(){return background;}
private Color background = Color.black; //Reset in reset
private Color lineColor = Color.red; //
private int hue = 270;
public void manageChange(uParameter uP){
int idx=uP.getIndex();
//dB.dbg( 2,"In Lines, Change in : "+uP.getName());
if (uPs[idx]!=null) uPs[idx]=uP; //ensures that uPs, the list of current parameters is up to date
switch (idx){
case VIEWSIZE:
//no problem since the points gravitate toward the middle
// but need to reset the screen and reinitialize
reset();
break;
case NUMBER:
number=uP;
reset();
break;
case PARA4: //used for speed or actually density
// do not need to reset here but need to reset max speed for
// the corners
speed=uP;
vv=speed.getCur();
for (int i=0; i<nc; i++)
corner[i].setMaxSpeed(vv);
break;
case PARA5: // used for number of corners in the polygons
ncorners=uP;
nc=uP.getCur();
//Should modify uParameter number
int np_max=(int)(nn_max/nc);
np = (np < np_max)? np : np_max;
uParameter num = new uParameter
(NUMBER, number.getName(), np_min,
np, np_max, number.getDescr());
number=num;
uPs[NUMBER]=num;
reset();
break;
case PARA6: // for new colorcombinations
colorcomb=uP;
reset();
break;
}
} // end manageChange
// end of Section 2
// Section 3 uParameters as used in the universe
// -----------------------------------------------------------------------
private uParameter number; //Number of lines requested - PARAMETER
private int np_min=2,np_cur=40; // nn_max is a static variable
private int np=np_cur; //actual number of polygons
private String ndescr=
"This parameter indicates the number of Polygons on the "+
"screen at any one time. The number of visible Polygons remain "+
"constant after initial growth to the maximum.";
// max speed of any EndPoint in x or y direction - PARAMETER
private uParameter speed;
private int vv=5,vv_max=30,vv_min=1;
private String sdescr=
"The 'Speed' is the maximum speed in pixels in the x or the y "+
"directions. Higher speeds tend to give a clutterd look.";
// max number of corners in a polygon - PARAMETER
private uParameter ncorners;
private int nc=3, nc_min=2; // nc_max = 6 is static
private String ncornersdesc =
" A polygon is described by the number of corners. This "+
"universe allows polygons with two corners (a line) and up "+
"to six corners.";
// colorcombinations of linecolor on background color - PARAMETER
// The following is new for version 1.2:
private uParameter colorcomb;
private String ccdescr=
"Select line colors against a background from one of the following: "+
"Black lines on white background, white lines on black, or lines "+
" whose color is stepped through 26 shades of color against a "+
"background selected from the thirteen primary Java colors.";
static String colornames[]={ " Black on White", " White on Black",
" Black background"," Blue background"," Cyan background",
" Dark grey background", " Grey background",
" Green background"," Light grey background"," Magenta background",
" Orange background", " Pink background"," Red background",
" White background"," Yellow background"};
static Color colors[]= // Standard Java Colors
{Color.black,Color.blue,Color.cyan,Color.darkGray,Color.gray,
Color.green,Color.lightGray,Color.magenta,Color.orange,Color.pink,
Color.red,Color.white,Color.yellow };
// end of this addition for v. 1.2
// cycletime is set here but otherwise handled in the rartrunners
public uParameter cycletime;
private void setParams(){
number= new uParameter
(NUMBER,"Number of Polygons",np_min,np_cur,nn_max/nc,ndescr);
// The adduParameter() method is defined in Universe
adduParameter(number);
speed=new uParameter(PARA4,"Speed",vv_min,vv, vv_max, sdescr);
adduParameter(speed);
ncorners = new uParameter
(PARA5, "Number of Corners", nc_min, nc, nc_max,ncornersdesc);
adduParameter(ncorners);
// The following two statements are new for v 1.2:
colorcomb = new uParameter
(PARA6,"Color Combination",cc,colornames, ccdescr);
adduParameter(colorcomb);
// Since "Cycle Time" is a compulsory parameter, Universe actually
// provides the description
cycletime= new uParameter(CYCLETIME,"Cycle Time", 10,25,100, CycleTimeDescr);
adduParameter(cycletime);
} // end of params
public Polygons() throws InstantiationException {}
} // end of class Polygons
>
TOP
>
import java.awt.*;
import rartbase.*;
/** -----------------------------------------------------------------------
* Class: EndPoint, the EndPoint moves in steps of fixed increments (or
* speed)across the screen until it hits a border when it is redirected in
* a new direction with a new speed.
*/
class EndPoint extends Point {
public static int BORDERWIDTH=20; // EndPoints bounce when coming within
// BORDERWIDTH pixels of any edge of the screen
private int bw=BORDERWIDTH; // just to save typing
private int dx; // current velocity in x dir
private int dy; // current velocity in y dir
private int xm; // width of window set in constructor
private int ym; // height of window set in constructor
private int vv; // maximum speed of point set in constructor
/**
* Constructor
* The initial poition of an endpoint is within the rectangle described by
* (bw, bw, x_max-2*bw, y_max-2*bw) where bw is the BORDERWIDTH.
*
* @x_max the width of the window in pixels
* @y_max the height of the window in pixels
* @v_max the maximum stepping speed of the EndPoint
*/
EndPoint(int x_max, int y_max, int v_max) {
xm=x_max;
ym=y_max;
vv=v_max;
setMaxSpeed(vv);
x = bw+RND(x_max-2*bw);
y = bw+RND(y_max-2*bw);
dx = setSpeed(vv);
dy = setSpeed(vv);
} // end EndPoint constructor
/**
* sets the maximum speed in x and y direction
*
* @v speed, greater than 0 and smaller than 50
*/
public void setMaxSpeed(int v){
v= (v<1)? 1: (v>50)? 50: v;
vv=v;
} // end setMaxSpeed
/**
* The move method encapsulates the behaviour where a point is stepped in
* discrete increments (dx and dy) until it hits an edge when its
* direction is reversed and the speed paralell to the edge given a new
* random value, effectively bouncing the point at random.
*
*/
public void move(){
x += dx; //Step x
y += dy; //Step y
// Check to see if the point hit the edge in x-direction
if (x < bw || x > (xm - bw)){
dx = (x<bw)? ABS(dx):-ABS(dx); // always moving toward center
x += 2*dx; // double back
dy = setSpeed(vv); // change speed in y-direction
}
// Check to see if the point hit the edge in y-direction
if (y < bw || y > (ym - bw)){
dy = (y<bw)? ABS(dy):-ABS(dy); // always moving toward center
y += 2*dy; // double back
dx = setSpeed(vv); // change speed in x-direction
}
} // end move
// Following two methods taken from Universe
private static int RND(int x){
return(Universe.RND(x));
}
private static int ABS(int x){
return(Universe.ABS(x));
}
private int setSpeed(int v){
int v1;
do{
// The following ensures speed distributed randomly in the
// interval [-v , v] endpoints included and 0 excluded.
v1=(RND(3)-1)*(1+RND(v));
}while (v1==0); // speed never 0!
return v1;
} // end of setSpeed
} // end of EndPoint
>