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

public class WUCircle extends Applet{

     //==========================================================================
     //Algorithm:
     //--------------------------------------------------------------------------

     //Principal:
         int I=255;           //Intensity.
         int A=2;             //Accuracy determained by argument of the root function D.
                             //   R < 10^A
                             //   Memory = 4 * 10^(2A)
                             //      For example:
                             //          for memory 40K (small machines), screens not more than about 100*100,
                             //          for memory 4Meg, screens about 1000*1000.
     //Auxiliary:
         int[] D;             //Precalcuated reversed fractions of roots.
         private static int POWERES_OF_TEN[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };

     private void initD(){
         int p = POWERES_OF_TEN[A*2];
         D = new int[p];
         for( int i=0; i<p; i++ ){  
             int f = (       (int)(I*Math.sqrt((double)i))       )%I;
             D[i] =  f == 0 ? 0 : I-f;
         }
         D[0] = 0;  //Secure from floating point errors on poor platforms.         
     }

     //Input: uses precalculated variables D and I.     
     public void drawArch( int R ) {
        int y=0;
        int x=R;
        int d=0;
        while( y<x ) {
            int dnew = D[R*R-y*y];
            if( dnew < d ) x--;
            putpixel(x-1,y,   dnew,  doDemo);
            putpixel(x,  y,(I-dnew), !doDemo);
            y++;
            d = dnew;
        }    
     }
     //--------------------------------------------------------------------------
     //End of Algorithm.
     //==========================================================================

             
     //Test:
     int R=20;            //Radius.     
         
     //Platform specific graphics auxiliary.
     Dimension scrDimension;
     Image img;
     Graphics g;
     boolean imageIsReady = false;

     //Graphics Aux:
     int xCenter = 5;
     int yCenter;
     int squareSize = 14;

     //Demonstration 
     boolean doDemo = true;
     int lightBackground = 0;
     Color realCurveColor = new Color( 255,0,0 );
     
     public void init(){
         
         //Preparation:
         try{ String s=getParameter("Radius"); if( s != null && s != "" ) R = Integer.parseInt(s); }catch( Exception e ) {};
         scrDimension = new Dimension( (squareSize*R+400), (squareSize*R+200) );
         yCenter = R * 12 / 10;
         setSize(scrDimension);
         img = createImage( scrDimension.width, scrDimension.height );
         g = img.getGraphics();
          
         //Algorithm Principal:        
         con( "initRoot" );
         initD();
         setImageBackground(255);
         con("DrawArch");
         drawArch(R);
         drawCoodinateLines(R);
         if(doDemo) drawRealCircleInDemo(R);
         imageIsReady = true;
         //con("repaint");
         repaint();
    }      

    
    
    private void putpixel( int x, int y, int intensity, boolean addDescription ){
        
        //Demo Circle:
        con("put: x=" + x + " y=" + y + " i=" + intensity);
        int i = lightBackground == 1 ? I - intensity : intensity; 
        g.setColor( new Color( i, i, i ) );
        int xScr = (xCenter+x)*squareSize;
        int yScr = (yCenter-y)*squareSize;
        g.fillRect( xScr, yScr, squareSize, squareSize);
        g.setColor(realCurveColor);
        int sQ2 = squareSize/2;
        if(addDescription) g.drawString( "x=" + x + "," + ((float)Math.sqrt(R*R-y*y)) + "," + (x+1) + "    y=" + y + "    i=" + intensity + "," + (I-intensity), xScr+3*squareSize, yScr+sQ2);
        
        //Real Circle:
        int rX = xCenter*squareSize + sQ2 + x;
        int rY = yCenter*squareSize + sQ2 - y;
        g.setColor(new Color(i,i,i));
        g.drawLine( rX, rY, rX, rY );
        
    }

    private void setImageBackground(int background){
        int xSize = scrDimension.width;
        int ySize = scrDimension.height;
        int c = background*lightBackground;
        g.setColor( new Color(c,c,c) );
        g.fillRect( 0, 0, xSize, ySize );
    } 
    
    private void drawCoodinateLines(int R){
        g.setColor(new Color(0,0,255));
        int sQ2 = squareSize/2;
        int x1 = xCenter*squareSize+sQ2;
        int x2 = (xCenter + R)*squareSize+sQ2;
        int y1 = yCenter*squareSize+sQ2;
        int y2 = (yCenter-R)*squareSize+sQ2;
        g.drawLine( x1, y1, x2, y1 );     //Axis x.
        g.drawLine( x1, y1, x1, y2 );     //Axis y.
        g.drawString( "Accuracy=" + A + "  Memory~" + (D.length * 4) + " bytes.     Intensity=" + I + "  Radius=" + R,  x1 + 40, y1 + 20);
    }


    private void drawRealCircleInDemo( int R ){
        g.setColor(realCurveColor);
        int sQ2 = squareSize/2;
        int sXCenter = xCenter*squareSize;
        int sYCenter = yCenter*squareSize;
        int sR=R*squareSize;
        int x=sR;
        int y=0;
        while(y<x){
           x = (int) Math.sqrt((double)(sR*sR-y*y));
           int xC = sXCenter+x+sQ2;
           int yC = sYCenter-y+sQ2;
           g.drawLine(xC,yC,xC,yC);
           y++;
        }
        
    }        

    public void paint( Graphics g ) {
       //con("update.  " + "imageIsReady=" + imageIsReady + "  image=" + img);
       if( imageIsReady && img != null ) {
           con( "draw image" );
           //Move result image to master image:
           g.drawImage( img, 0,0, null );
       }
     }
   
    public static void prn( Object ob ){
      System.out.println( ob );
    }

    static public void con( Object ob) {
        String s1 = "      " + System.currentTimeMillis();
        int wLen = s1.length();
        s1 = s1.substring( wLen - 7, wLen-1 );
        String s2 =Thread.currentThread().getName() + "                    ";
        s2 = s1 + "  \"" + s2.substring ( 0, 20 ) + "\"  " + ob;
        System.out.println(s2);
    }//con
   
}//class


Copyright_C_2008_Landkey_Computers.txt