//Graphics algorithms: //Bresenham's style: // WU // http://www.mini.pw.edu.pl/~kotowski/Grafika/RasterDrawing/Index.html // Apparently, // there is a typo: // ... // y++; // if (D(R,y)<T) // Initial T=0, and D >= 0 for circle's points which are not on the grid. // // Therefore, this condition never works. // x--; // ... class TestsWU { public static void main( String args[] ) { for( int accuracy = 1; accuracy<8; accuracy++ ) //accuracy = 8 gives array of 100 000 000 of int32 = 400Mbytes //which gives java.lang.OutOfMemoryError: Java heap space ... //in our 1 Gig RAM PC. { long start = System.currentTimeMillis(); String s = InitializeISqrt( accuracy ); if( s == "" ){ System.out.println( "Total Duration=" + ( System.currentTimeMillis() - start) + " milliseconds." ); System.out.println( "Duration per array element =" + ( 1000000. * ( System.currentTimeMillis() - start)) / ISqrt.length + " nanoseconds." ); int arg = 0; ISQRT(arg); System.out.println( "sqrt(" + arg + "0)="+ ISignificand + " * 10^-" + IExponent); arg = 1; ISQRT(arg); System.out.println( "sqrt(" + arg + "0)="+ ISignificand + " * 10^-" + IExponent); arg = 20000; ISQRT(arg); System.out.println( "sqrt(" + arg + "0)="+ ISignificand + " * 10^-" + IExponent); arg = 999999; ISQRT(arg); System.out.println( "sqrt(" + arg + "0)="+ ISignificand + " * 10^-" + IExponent + "\r\n\r\n\r\n"); } else { System.out.println( s ); } } } //To not exceede limts of int32: private static final int SAFE_DIGITS = 6; private static int ROOTS_ARRAY_SIZE; //Redundant digits which exceed accuracy restricted by ACCURACY: private static int BONUS_DIGITS; private static int BONUS_MULTIPLIER; //Auxiliary array to store precalculated powers of 10: private static int POWERES_OF_TEN[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; //Primary array where precalculated roots will be stored: private static int[] ISqrt; //ACCURACY value 3 should provide sqrt(10^3) accuracy ~ 3% accuracy. //ACCURACY value 4 should provide sqrt(10^4) accuracy ~ 1% accuracy. // In application to IntegerWU algorithm to find Intensity*ceil(sqrt(RR-yy)), // this will give 100 grades of shade which should be good. //ACCURACY value 5 should provide sqrt(10^5) accuracy ~ .3% accuracy. public static String InitializeISqrt(int ACCURACY) { System.out.println( "ACCURACY=" + ACCURACY + ". SAFE DIGITS=" + SAFE_DIGITS ); if( ACCURACY < 3 ) { return "ACCURACY is too small: ACCURACY < " + 3; } int w = 2 * SAFE_DIGITS - ACCURACY; BONUS_DIGITS = (w - (w%2)) / 2; if( BONUS_DIGITS < 0 ) { return "ACCURACY is too big: ACCURACY > " + (2 * SAFE_DIGITS); } ROOTS_ARRAY_SIZE = POWERES_OF_TEN[ACCURACY]; BONUS_MULTIPLIER = POWERES_OF_TEN[BONUS_DIGITS]; System.out.println( "ROOTS_ARRAY_SIZE=" + ROOTS_ARRAY_SIZE + ". BONUS_DIGITS=" + BONUS_DIGITS + ". BONUS_MULTIPLIER=" + BONUS_MULTIPLIER + "."); ISqrt = new int[ ROOTS_ARRAY_SIZE ]; for( int i=0; i<ROOTS_ARRAY_SIZE; i++ ){ ISqrt[i] = (int) ( Math.sqrt((double)i) * BONUS_MULTIPLIER ); } return ""; } //Calculating square root represented by integer numbers. //Input x>=0. //Output: ISignificand * 10^IExponent // where public static int IExponent; public static int ISignificand; public static void ISQRT( int x ) { int shift=0; if ( x!=0 ) { while ( x<ROOTS_ARRAY_SIZE ) { x = x*100; shift -=1; } } while ( x>=ROOTS_ARRAY_SIZE ) { x = x/100; shift +=1; } IExponent = BONUS_DIGITS-shift; //System.out.println("x=" + x + ". Len=" + ISqrt.length ); ISignificand = ISqrt[x]; } //This function calculates D(R,y) = ceil(sqrt(RR-yy)) - sqrt(RR-yy). //It returns distance scaled with FullIntensity. //Input: FullIntensity < 2000. (To avoid integer overflow when FullIntensity * id.) // R<1000. Otherwise, no guarantee for accuracy. private static int ID( int R, int y, int FullIntensity ) { ISQRT( R*R-y*y ); int p = POWERES_OF_TEN[IExponent]; int id = ISignificand % p; return FullIntensity * id / p; } } Copyright_C_2008_Landkey_Computers.txt