/*===================================================================*/ /* PointRotation.java */ /*===================================================================*/ /** *
 * PointRotation: An action-packed applet that constructs a wire
 *                 frame object out of a set of random points, and
 *                 draws/rotates the object.  A simple polygon is
 *                 also drawn for perspective.
 *
 *                The drawing is handles by a thread.
 *
 * Revisions:  1.0  June 13, 1998,
 *                  Created class PointRotation
 *
 * Overview:  This simple applet creates an array of random points,
 *            called xs[], ys[], and zs[].  The points are then
 *            rotated, with the updated coordinates stored in
 *            xt[], yt[], and zt[].  A thread continuously updates
 *            the angular rotation of the points, and draws them
 *            to the screen.
 *
 *
 *   Applet drawing area __
 *                         |
 *                         |
 *                         V
 *
 *     +------------------------+
 *     |                        |
 *     |                        |
 *     |                        |
 *     |          *-----*  <------------- Points being drawn
 *     |          |   //|       |           xt[0], yt[0]
 *     |          *-/ / |       |           xt[1], yt[1]
 *     |           \ /  |       |           xt[2], yt[2]
 *     |            * --*       |            etc. etc.
 *     |                        |
 *     |                        |
 *     |                        |         World Coord points
 *     |                        |           xs[0], ys[0], zs[0]
 *     +------------------------+           xs[1], ys[1], zs[1]
 *                                          xs[2], ys[2], zs[2]
 *                                          xs[3], ys[3], zs[3]
 *                                           etc.
 *
 *
 * 
* * @author David Dagon * @version Version 1.0, June 13, 1998 */ /*===================================================================*/ import java.awt.*; import java.applet.*; public class PointRotation extends Applet implements Runnable { /*===================================================================*/ /* INSTANCE VARIABLES */ /*===================================================================*/ /*----------------- Data Variables -----------------------*/ private int pts; // how many points? private double xs[], // source array of coordinates ys[], zs[], xt[], // array of translated coords. yt[], zt[]; private double Ax, // angles Ay, Az; private double Vx, // angular velocities Vy, Vz; /*------------------- Thread Variables --------------------*/ private Thread daThread; // the animation thread /*------------------- Graphics/Misc. Variables ------------*/ public int i; // a counter public int pause; // how long a wait? private int Xorig, // center of screen Yorig, xc, // current coords xp, // being drawn yc, // previous coords drawn yp; private Polygon p; // drawn for perspective private int radius; // how big are the dots? public double Xa, // trash vars used rotation Ya, Za, Xb, Yb, Zb; private Graphics osG; // double buffering private Image osImg; /*===================================================================*/ /* INITIALIZATION */ /*===================================================================*/ /** *
*
*  init -- initialize variables
*
*  Precondition: The applet has started
*  Postcondition: Variables are intialized, arrays populated
*     and the animation thread started
*
* 
* * @see java.applet.Applet#init -- called to initialze applet panel * * @see java.awt.Component#size -- called to return size * * @see this#start -- called to start animation thread * * @see java.lang.Thread -- constructor call * * @deprecated size() -- called instead of JDK 1.1 method getSize(), * because Netscape barfs */ public void init() { // always call super.init() super.init(); // initialize variables pts = 4; radius = 5; pause = 5; Xorig = size().width>>1; // same as dividing by two Yorig = size().height>>1; xs = new double[pts]; ys = new double[pts]; zs = new double[pts]; xt = new double[pts]; yt = new double[pts]; zt = new double[pts]; // get some random points for (i=0; i< pts; i++) { xs[i] = Math.random()*250-(25*i); ys[i] = Math.random()*250-(25*i); zs[i] = Math.random()*250-(25*i); } // for loop populating array // These variables deterine the rate of rotation. Vx = Math.PI/60; Vy = Math.PI/80; Vz = Math.PI/90; // start up the thread daThread = new Thread(this); daThread.start(); } // init /*===================================================================*/ /* THREAD METHODS */ /*===================================================================*/ /** *
*
*       run -- animate the thread
*
*   Precondition: The thread has been instantiated, and has started
*
*   Postcondition: The points are rotated, and the wire frame image
*       updated
*
*   
* * @see java.lang.Thread#sleep -- called to pause animation * * @see java.lang.Throwable#printStackTrace -- called in event * the sleep call is interrupted * * @see this#rotateEm() -- called to rotate the points * * @see java.awt.Component#repaint -- called to update image * after rotation */ public void run() { while (daThread!=null) { // take a nap try {daThread.sleep(pause);} catch (InterruptedException dammit) {dammit.printStackTrace();} // update points and refresh rotateEm(Ax,Ay,Az); repaint(); //update angles Ax+=Vx; Ay+=Vy; Az+=Vz; } } // run /*===================================================================*/ /** *
*
*      start -- get the thread started up
*
*      Precondition: The thread has been instantiated, and
*         start() has been called on it
*
*      Postcondition: If the thread is null, it
*         is instaniated and started.
*
*   
* * @see java.lang.Thread -- constructor call * * @see this#start() -- recursively called if thread is null */ public void start() { if (daThread == null) { daThread = new Thread(this); daThread.start(); } } /*===================================================================*/ /** * *
*
*     stop -- stop that Thread!
*
*     Precondition: The applet page has been abandoned, or
*       some other process has called stop on the applet
*
*     Postcondition: If not null, the applet stops
*
*
*  
*/ public void stop() { if (daThread != null) { daThread.stop(); daThread = null; } } //stop /*===================================================================*/ /* GRAPHICS METHODS */ /*===================================================================*/ /** *
*
*    paint -- draw the points, using double buffering
*
*    Precondition: The points have been rotated, and need refreshing
*
*    Postcondition: The points are drawn, a wire frame connecting
*           them to their origin, and a single polygon is filled
*           for perspective
*
*  
* * @see java.awt.Component#getBackground * * @see java.awt.Component#size() -- called to return size of the * drawing surface * * @see java.awt.Component#createImage() -- called to create offscreen * image for buffering * * @see java.awt.Component#getGraphics() -- called to return graphics * context of offscreen image * * @see java.awt.Polygon -- constructor call * * @see java.awt.Graphics#drawLine() -- called to draw wire frame * * @see java.awt.Graphics#fillOval() -- called to create 'dots' for all * the vertices being rendered * * @see java.awt.Graphics#setColor() -- called to adjust color of * graphics object * * @see java.awt.Graphics#fillPolygon() -- called to draw a single * polygon to help with perspective * * @see java.awt.Graphics#drawImage() -- called to blit offscreen * buffer to screen when completed * * @see java.awt.Graphics#fillRect() -- called to clean up the * offscreen object * * @deprecated size() -- called in place of JDK 1.1 getSize() method, * since Netscape usually barfs on this. * * @param Graphics g -- the graphics object of the applet * */ public void paint (Graphics g) { // if the buffer is not valid, create it if (osG == null) { osImg = createImage(size().width, size().height); osG= osImg.getGraphics(); // calculate center of applet Xorig = size().width>>1; Yorig = size().height>>1; } // set up of buffer // clean slate osG.setColor(getBackground()); osG.fillRect(0,0,size().width, size().height); // draw a simple polygon p=new Polygon(); for (i=0; i * * updae -- overridden to smooth double buffering * * Precondition: The applet is in need of updating * * Postcondition: The applet is not redrawn; instead, * repaint is called * * * * @see this#paint() -- called to complete drawing * * @param Graphics g -- the Applet's graphics context */ public void update(Graphics g) { paint(g); } // update /*===================================================================*/ /** * *
*
*   invalidate -- override invalidate to dispose of buffer
*
*   Precondition: An invalidating event has taken place (e.g.
*           resizing of appletviewer)
*
*   Postcondition: The offscreen buffer is set to null
*
* 
* * @see java.awt.Component#invalidate -- called to restore * functionality of method */ public void invalidate() { super.invalidate(); osG=null; } // invalidate /*===================================================================*/ /* DATA MANIPULATION METHODS */ /*===================================================================*/ /** *
*
*  rotateEm -- rotate the points
*
*  Precondition: A change in angles has been calculated
*
*  Postcondition: The points are rotated by the adjusted angles
*
* 
* * @see java.lang.Math#sin() -- called to calulate sin * * @see java.lang.Math#cos() -- called to calculate cos * * @param double a -- the x angle value * * @param double b -- the y angle value * * @param double c -- the z angle value * */ public void rotateEm (double a, double b, double c) { for (i=0; i< pts; i++) { Xa=xs[i]*Math.cos(a)-ys[i]*Math.sin(a); Ya=xs[i]*Math.sin(a)+ys[i]*Math.cos(a); Za = zs[i]; Xb=Xa; Yb = Ya*Math.cos(b) - Za*Math.sin(b); Zb = Ya*Math.sin(b) + Za*Math.cos(b); xt[i]=Xb*Math.cos(c) + Zb *Math.sin(c); yt[i]=Yb; zt[i]= -Xb*Math.sin(c) + Zb*Math.cos(c); } // for loop } // rotateEm /*===================================================================*/ }