Friday, March 16, 2012

Codes Yet to be Discovered

Those are the only awesome codes I know so far and some are yet to be discovered.

Comment away!
Some tips:



Audio
To play audio files, use Applet.play(). Java 1.1 only supports Sun Audio (.au) files, or specifically, 8 bit, u-law, 8000 Hz, one-channel Sun format. BothApplet.play() and AudioClip.play() are non-blocking: they return immediately after starting the playback of the audio file. Try here for an example.
Applet Info
You can embed information about your applet inside itself by defining getAppletInfo() and getParameterInfo().
Debugging Tips
If you're having trouble understanding what your applet is doing (or not doing), use System.out.println() and showStatus() to print out the values of variables and information about where the program is.
Browsers won't normally reload applets after they've been loaded once. If you test an applet inside your browser, and then modify the applet's source code and recompile, simply reloading the webpage in your browser isn't enough to view the new applet. You'll have to exit and restart your browser. To avoid this nuisance, do initial testing of applets with appletviewer rather than a web browser.
Conditional Compilation
In C, blocks of code can be conditionally compiled using #define flags thus:
#define FLAG 1
...
#ifdef FLAG
...
#else
...
#endif
Java is not as flexible, but allows for something that is sometimes just as good:
private static final boolean DEBUG = false;
...
if ( DEBUG ) {
   ...
}
else {
   ...
}
The final keyword means the variable is constant, so unless your compiler's optimizer is brain-dead, it should prune out the conditional and the unreachable block of code.
Odds and Ends





import java.applet.*;
import java.awt.*;
import java.lang.Math;
 
public class ArchimedianSpiral extends Applet {
 
   int width, height;
   int N = 30; // number of points per full rotation
   int W = 5;  // winding number, or number of full rotations
 
   public void init() {

      width = getSize().width;
      height = getSize().height;
      setBackground( Color.black );
      setForeground( Color.green );
   }
 
   public void paint( Graphics g ) {

      int x1 = 0, y1 = 0, x2, y2;
      for ( int i = 1; i <= W*N; ++i ) {
         double angle = 2*Math.PI*i/(double)N;
         double radius = i/(double)N * width/2 / (W+1);
         x2 = (int)( radius*Math.cos(angle) );
         y2 = -(int)( radius*Math.sin(angle) );
         g.drawLine( width/2+x1, height/2+y1, width/2+x2, height/2+y2 );
         x1 = x2;
         y1 = y2;
      }
   }
}

One of the largest codes....Click and drag on the applet to rotate the cube:



import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.Math;

class Point3D {
   public int x, y, z;
   public Point3D( int X, int Y, int Z ) {
      x = X;  y = Y;  z = Z;
   }
}

class Edge {
   public int a, b;
   public Edge( int A, int B ) {
      a = A;  b = B;
   }
}

public class WireframeViewer extends Applet
   implements MouseListener, MouseMotionListener {

   int width, height;
   int mx, my;  // the most recently recorded mouse coordinates

   Image backbuffer;
   Graphics backg;

   int azimuth = 35, elevation = 30;

   Point3D[] vertices;
   Edge[] edges;

   public void init() {
      width = getSize().width;
      height = getSize().height;

      vertices = new Point3D[ 8 ];
      vertices[0] = new Point3D( -1, -1, -1 );
      vertices[1] = new Point3D( -1, -1,  1 );
      vertices[2] = new Point3D( -1,  1, -1 );
      vertices[3] = new Point3D( -1,  1,  1 );
      vertices[4] = new Point3D(  1, -1, -1 );
      vertices[5] = new Point3D(  1, -1,  1 );
      vertices[6] = new Point3D(  1,  1, -1 );
      vertices[7] = new Point3D(  1,  1,  1 );

      edges = new Edge[ 12 ];
      edges[ 0] = new Edge( 0, 1 );
      edges[ 1] = new Edge( 0, 2 );
      edges[ 2] = new Edge( 0, 4 );
      edges[ 3] = new Edge( 1, 3 );
      edges[ 4] = new Edge( 1, 5 );
      edges[ 5] = new Edge( 2, 3 );
      edges[ 6] = new Edge( 2, 6 );
      edges[ 7] = new Edge( 3, 7 );
      edges[ 8] = new Edge( 4, 5 );
      edges[ 9] = new Edge( 4, 6 );
      edges[10] = new Edge( 5, 7 );
      edges[11] = new Edge( 6, 7 );

      backbuffer = createImage( width, height );
      backg = backbuffer.getGraphics();
      drawWireframe( backg );

      addMouseListener( this );
      addMouseMotionListener( this );
   }

   void drawWireframe( Graphics g ) {

      // compute coefficients for the projection
      double theta = Math.PI * azimuth / 180.0;
      double phi = Math.PI * elevation / 180.0;
      float cosT = (float)Math.cos( theta ), sinT = (float)Math.sin( theta );
      float cosP = (float)Math.cos( phi ), sinP = (float)Math.sin( phi );
      float cosTcosP = cosT*cosP, cosTsinP = cosT*sinP,
             sinTcosP = sinT*cosP, sinTsinP = sinT*sinP;

      // project vertices onto the 2D viewport
      Point[] points;
      points = new Point[ vertices.length ];
      int j;
      int scaleFactor = width/4;
      float near = 3;  // distance from eye to near plane
      float nearToObj = 1.5f;  // distance from near plane to center of object
      for ( j = 0; j < vertices.length; ++j ) {
         int x0 = vertices[j].x;
         int y0 = vertices[j].y;
         int z0 = vertices[j].z;

         // compute an orthographic projection
         float x1 = cosT*x0 + sinT*z0;
         float y1 = -sinTsinP*x0 + cosP*y0 + cosTsinP*z0;

         // now adjust things to get a perspective projection
         float z1 = cosTcosP*z0 - sinTcosP*x0 - sinP*y0;
         x1 = x1*near/(z1+near+nearToObj);
         y1 = y1*near/(z1+near+nearToObj);

         // the 0.5 is to round off when converting to int
         points[j] = new Point(
            (int)(width/2 + scaleFactor*x1 + 0.5),
            (int)(height/2 - scaleFactor*y1 + 0.5)
         );
      }

      // draw the wireframe
      g.setColor( Color.black );
      g.fillRect( 0, 0, width, height );
      g.setColor( Color.white );
      for ( j = 0; j < edges.length; ++j ) {
         g.drawLine(
            points[ edges[j].a ].x, points[ edges[j].a ].y,
            points[ edges[j].b ].x, points[ edges[j].b ].y
         );
      }
   }

   public void mouseEntered( MouseEvent e ) { }
   public void mouseExited( MouseEvent e ) { }
   public void mouseClicked( MouseEvent e ) { }
   public void mousePressed( MouseEvent e ) {
      mx = e.getX();
      my = e.getY();
      e.consume();
   }
   public void mouseReleased( MouseEvent e ) { }
   public void mouseMoved( MouseEvent e ) { }
   public void mouseDragged( MouseEvent e ) {
      // get the latest mouse position
      int new_mx = e.getX();
      int new_my = e.getY();

      // adjust angles according to the distance travelled by the mouse
      // since the last event
      azimuth -= new_mx - mx;
      elevation += new_my - my;

      // update the backbuffer
      drawWireframe( backg );

      // update our data
      mx = new_mx;
      my = new_my;

      repaint();
      e.consume();
   }

   public void update( Graphics g ) {
      g.drawImage( backbuffer, 0, 0, this );
      showStatus("Elev: "+elevation+" deg, Azim: "+azimuth+" deg");
   }

   public void paint( Graphics g ) {
      update( g );
   }
}

Note that the time displayed in the lower left corner may not be correct -- certain browsers (perhaps only older versions?) seem to interpret the "default" time zone as something different from the local time zone. (The hands, however, always seem to display the correct time.) If this problem bothers you, try using
timeString = date.toString();
instead of
timeString = formatter.format( date );

Understand:
import java.applet.*;
import java.awt.*;
import java.util.*;
import java.text.*;

public class Clock1 extends Applet implements Runnable {

   int width, height;
   Thread t = null;
   boolean threadSuspended;
   int hours=0, minutes=0, seconds=0;
   String timeString = "";

   public void init() {
      width = getSize().width;
      height = getSize().height;
      setBackground( Color.black );
   }

   public void start() {
      if ( t == null ) {
         t = new Thread( this );
         t.setPriority( Thread.MIN_PRIORITY );
         threadSuspended = false;
         t.start();
      }
      else {
         if ( threadSuspended ) {
            threadSuspended = false;
            synchronized( this ) {
               notify();
            }
         }
      }
   }

   public void stop() {
      threadSuspended = true;
   }

   public void run() {
      try {
         while (true) {

            // Here's where the thread does some work
            Calendar cal = Calendar.getInstance();
            hours = cal.get( Calendar.HOUR_OF_DAY );
            if ( hours > 12 ) hours -= 12;
            minutes = cal.get( Calendar.MINUTE );
            seconds = cal.get( Calendar.SECOND );

            SimpleDateFormat formatter
               = new SimpleDateFormat( "hh:mm:ss", Locale.getDefault() );
            Date date = cal.getTime();
            timeString = formatter.format( date );

            // Now the thread checks to see if it should suspend itself
            if ( threadSuspended ) {
               synchronized( this ) {
                  while ( threadSuspended ) {
                     wait();
                  }
               }
            }
            repaint();
            t.sleep( 1000 );  // interval given in milliseconds
         }
      }
      catch (InterruptedException e) { }
   }

   void drawHand( double angle, int radius, Graphics g ) {
      angle -= 0.5 * Math.PI;
      int x = (int)( radius*Math.cos(angle) );
      int y = (int)( radius*Math.sin(angle) );
      g.drawLine( width/2, height/2, width/2 + x, height/2 + y );
   }

   void drawWedge( double angle, int radius, Graphics g ) {
      angle -= 0.5 * Math.PI;
      int x = (int)( radius*Math.cos(angle) );
      int y = (int)( radius*Math.sin(angle) );
      angle += 2*Math.PI/3;
      int x2 = (int)( 5*Math.cos(angle) );
      int y2 = (int)( 5*Math.sin(angle) );
      angle += 2*Math.PI/3;
      int x3 = (int)( 5*Math.cos(angle) );
      int y3 = (int)( 5*Math.sin(angle) );
      g.drawLine( width/2+x2, height/2+y2, width/2 + x, height/2 + y );
      g.drawLine( width/2+x3, height/2+y3, width/2 + x, height/2 + y );
      g.drawLine( width/2+x2, height/2+y2, width/2 + x3, height/2 + y3 );
   }

   public void paint( Graphics g ) {
      g.setColor( Color.gray );
      drawWedge( 2*Math.PI * hours / 12, width/5, g );
      drawWedge( 2*Math.PI * minutes / 60, width/3, g );
      drawHand( 2*Math.PI * seconds / 60, width/2, g );
      g.setColor( Color.white );
      g.drawString( timeString, 10, height-10 );
   }
}



Programming a custom brush and canvas enables experimentation with behaviors not otherwise possible. An understanding of arithmetic, geometry, and trigonometry will enhance your own ability to "play" in this medium:





import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.Math;

public class Brush2 extends Applet
   implements MouseMotionListener {

   int width, height;
   Image backbuffer;
   Graphics backg;

   int mx, my;

   double t = 0;

   public void init() {
      width = getSize().width;
      height = getSize().height;

      mx = width / 2;
      my = height / 2;

      backbuffer = createImage( width, height );
      backg = backbuffer.getGraphics();
      backg.setColor( Color.black );
      backg.fillRect( 0, 0, width, height );
      backg.setColor( Color.white );

      addMouseMotionListener( this );
   }

   public void mouseMoved( MouseEvent e ) { }
   public void mouseDragged( MouseEvent e ) {
      int x = e.getX();
      int y = e.getY();
      int dx = x - mx;
      int dy = y - my;
      t += Math.sqrt( dx*dx + dy*dy ) / 20;
      if ( t > 2*Math.PI ) {
         t -= 2*Math.PI;
      }
      backg.drawLine( x, y, x+(int)(15*Math.cos(t)), y+(int)(15*Math.sin(t)) );
      mx = x;
      my = y;
      repaint();
      e.consume();
   }

   public void update( Graphics g ) {
      g.drawImage( backbuffer, 0, 0, this );
   }

   public void paint( Graphics g ) {
      update( g );
   }
}

Click and type; click again and type some more :


import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Keyboard3 extends Applet
   implements KeyListener, MouseListener {

   int width, height;
   int x, y;
   String s = "";
   Image backbuffer;
   Graphics backg;

   public void init() {
      width = getSize().width;
      height = getSize().height;
      setBackground( Color.black );

      x = width/2;
      y = height/2;

      backbuffer = createImage( width, height );
      backg = backbuffer.getGraphics();
      backg.setColor( Color.black );
      backg.fillRect( 0, 0, width, height );
      backg.setColor( Color.green );

      addKeyListener( this );
      addMouseListener( this );
   }

   public void keyPressed( KeyEvent e ) { }
   public void keyReleased( KeyEvent e ) { }
   public void keyTyped( KeyEvent e ) {
      char c = e.getKeyChar();
      if ( c != KeyEvent.CHAR_UNDEFINED ) {
         s = s + c;
         backg.drawString( s, x, y );
         repaint();
         e.consume();
      }
   }

   public void mouseEntered( MouseEvent e ) { }
   public void mouseExited( MouseEvent e ) { }
   public void mousePressed( MouseEvent e ) { }
   public void mouseReleased( MouseEvent e ) { }
   public void mouseClicked( MouseEvent e ) {
      x = e.getX();
      y = e.getY();
      s = "";
      repaint();
      e.consume();
   }

   public void update( Graphics g ) {
      g.drawImage( backbuffer, 0, 0, this );
      g.setColor( Color.gray );
      g.drawLine( x, y, x, y-10 );
      g.drawLine( x, y, x+10, y );
   }

   public void paint( Graphics g ) {
      update( g );
   }
}