Introduction to Java. A tutorial from A-SQUARE, Inc. January 2003

© 2000-2003 A-Square, Inc.


Source Code for Polygons.java including EndPoint.java

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

EndPoint.java

>

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

>

TOP