home *** CD-ROM | disk | FTP | other *** search
-
- #import "MandelView.h"
- #import "Thinker.h"
-
- #include "ms_real.h"
- #include "ms_real.c"
- //
- #include "time.h"
-
- //#define steps(a,b,c) mandelbrot(a,b,256)
- #define steps(a,b,c) (use_fixed ? mandelbrot(a,b,256) : newsteps(a,b) )
- #define RANDINT(n) (random() % (n))
- #define RANDFLOAT(f) (((f) * (float)(random() & 0x0ffff)) / (float)0x0ffff)
-
- int newsteps( double x, double y) ;
-
-
-
- @implementation MandelView
-
- void spreadNXColors( NXColor col1, NXColor col2, NXColor *targ, int n )
- {
- float cur_rgb[3], rgb_step[3] ;
- int i ;
-
- NXConvertColorToRGB( col2, &(rgb_step[0]), &(rgb_step[1]), &(rgb_step[2]) ) ;
- NXConvertColorToRGB( col1, &(cur_rgb[0]), &(cur_rgb[1]), &(cur_rgb[2]) ) ;
-
- rgb_step[0] -= cur_rgb[0] ;
- rgb_step[1] -= cur_rgb[1] ;
- rgb_step[2] -= cur_rgb[2] ;
-
- rgb_step[0] /= (n-1) ;
- rgb_step[1] /= (n-1) ;
- rgb_step[2] /= (n-1) ;
-
- for( i=0; i<n; i++) {
- targ[i] = NXConvertRGBToColor( cur_rgb[0], cur_rgb[1], cur_rgb[2] ) ;
- cur_rgb[0] += rgb_step[0] ;
- cur_rgb[1] += rgb_step[1] ;
- cur_rgb[2] += rgb_step[2] ;
- }
- }
-
- int newsteps( double x, double y)
- {
- register double x1, y1, xs, ys ;
- register int c;
-
- x1 = x ; y1 = y ;
-
- xs = x1 * x1 ;
- ys = y1 * y1 ;
- c = 0 ;
- while( (xs + ys < 4.0) && (c < 255) ) {
- y1 = 2 * x1 * y1 + y ;
- x1 = xs - ys + x ;
- c++ ;
- xs = x1 * x1 ;
- ys = y1 * y1 ;
- }
- return c ;
- }
-
- /* this routine was taken from mandelspawn 0.7 by Andreas Gustafsson,
- gson@niksula.hut.fi */
-
- /*
- This file is part of MandelSpawn, a network Mandelbrot program.
-
- Copyright (C) 1990-1993 Andreas Gustafsson
-
- MandelSpawn is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License, version 1,
- as published by the Free Software Foundation.
-
- MandelSpawn is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License,
- version 1, along with this program; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- int mandelbrot(parms0, parms1, maxiter )
- double parms0,parms1;
- int maxiter;
- {
- register real x_re, x_im;
- register real c_re, c_im;
- register real xresq, ximsq;
-
- int count;
-
-
- c_re = double_to_fixed(parms0);
- c_im = double_to_fixed(parms1);
- x_re = c_re ;
- x_im = c_im ;
-
- /* The following loop is where the Real Work gets done. */
- count=0;
- while(count < 255)
- {
- /*
- This is the familiar "z := z^2 + c; abort if |z| > 2"
- Mandelbrot iteration, with the arithmetic operators hidden
- in macros so that the same code can be compiled for either
- fixed-point or floating-point arithmetic.
- The macros (mul_real(), etc.) are defined in ms_real.h.
- */
- xresq=mul_real(x_re, x_re);
- ximsq=mul_real(x_im, x_im);
- if(gteq_real(add_real(xresq, ximsq), four_real()))
- break;
- x_im=add_real(twice_mul_real(x_re, x_im), c_im);
- x_re=add_real(sub_real(xresq, ximsq), c_re);
- count++;
- }
- return count;
- }
-
- - initFrame:(NXRect *)rect
- {
-
- sx = -1.5 ; ex = 1.0 ;
- sy = -1.5 ; ey = 1.5 ;
-
- [super initFrame:rect];
-
- [self allocateGState]; // For faster lock/unlockFocus
-
- [inspectorPanel display];
-
- color = NX_COLORYELLOW;
- alreadyInitialized = NO;
- randCount1 = 100;
- randCount2 = 200;
-
- drawing_mandel = TRUE ;
- frame_drawn = TRUE ;
- use_fixed = TRUE ;
- [self setColors:backWell ] ;
-
-
-
- or_w = 2.5 ;
-
- odx = or_w / bounds.size.width ;
- ody = odx ;
-
- or_x = -2.0 ;
- or_y = -1.25 ;
-
- best_lost = 0 ;
- best_max_stack = 0 ;
- best_draw_length = 0 ;
- draw_length = 0 ;
-
- stack = 0 ;
- todo[0].sx = 0 ;
- todo[0].ex = bounds.size.width ;
- todo[0].sy = 0 ;
- todo[0].ey = bounds.size.height ;
- todo[0].c = steps( or_x, or_y, 255 ) ;
-
- return self;
- }
-
- - drawSelf:(const NXRect *)rects :(int)rectCount
- {
- if (!rects || !rectCount) return self;
- [super drawSelf:rects :rectCount];
- return self;
- }
-
- - setColors:sender
- {
- mypal[255] = [backWell color] ;
-
- spreadNXColors( [Well1 color], [Well2 color], &(mypal[0]), 83 ) ;
- spreadNXColors( [Well2 color], [Well3 color], &(mypal[83]), 83 ) ;
- spreadNXColors( [Well3 color], [Well4 color], &(mypal[166]), 89 ) ;
-
- spreadNXColors( [Well1 color], [Well2 color], &(mypal[0]), 16 ) ;
- spreadNXColors( [Well2 color], [Well3 color], &(mypal[16]), 16 ) ;
- spreadNXColors( [Well3 color], [Well4 color], &(mypal[32]), 16 ) ;
- spreadNXColors( [Well4 color], [Well1 color], &(mypal[48]), 16 ) ;
- spreadNXColors( [Well1 color], [Well2 color], &(mypal[64]), 16 ) ;
- spreadNXColors( [Well2 color], [Well3 color], &(mypal[80]), 16 ) ;
- spreadNXColors( [Well3 color], [Well4 color], &(mypal[96]), 16 ) ;
- spreadNXColors( [Well4 color], [Well1 color], &(mypal[112]), 16 ) ;
- spreadNXColors( [Well1 color], [Well2 color], &(mypal[128]), 16 ) ;
- spreadNXColors( [Well2 color], [Well3 color], &(mypal[128+0]), 16 ) ;
- spreadNXColors( [Well3 color], [Well4 color], &(mypal[128+16]), 16 ) ;
- spreadNXColors( [Well4 color], [Well1 color], &(mypal[128+32]), 16 ) ;
- spreadNXColors( [Well1 color], [Well2 color], &(mypal[128+48]), 16 ) ;
- spreadNXColors( [Well2 color], [Well3 color], &(mypal[128+64]), 16 ) ;
- spreadNXColors( [Well3 color], [Well4 color], &(mypal[128+80]), 16 ) ;
- spreadNXColors( [Well4 color], [Well1 color], &(mypal[128+96]), 16 ) ;
- spreadNXColors( [Well1 color], [Well2 color], &(mypal[128+112]), 15 ) ;
-
- return self ;
- }
-
- - setImageConstraints
- {
- [super setImageConstraints];
-
- if (imageRect.origin.x > maxCoord.x ||
- imageRect.origin.y > maxCoord.y)
- {
- imageRect.origin.x = randBetween(0, maxCoord.x);
- imageRect.origin.y = randBetween(0, maxCoord.y);
- }
-
- return self;
- }
-
-
- #define gl_fillbox( x, y, h, w, c ) myfillbox( x, y, h, w, c,p )
-
- #define gl_setpixel(a, b, c)
-
- void myfillbox( int x, int y, int w, int h, int c, NXColor *p )
- {
- NXRect myrect2 ;
- // NXSetColor( NXConvertRGBToColor( (float) (c%17) / 17, (float)(c%39) / 39, 1-(float)(c%64)/64.0 )) ;
- NXSetColor( p[c] ) ;
- NXSetRect( &myrect2, x, y, w, h ) ;
- NXRectFill( &myrect2) ;
- }
-
- void just_do( sdata *s, double or_x, double or_y, double odx, double ody, int *counter, NXColor *p, int resolution, int use_fixed )
- {
- double x, y, init_x, init_y ;
- int i,j ;
-
- x = or_x + s->sx * odx ;
- y = or_y + s->sy * ody ;
- init_x = x ; init_y = y ;
- j = s->sx ; i=s->sy ;
- gl_fillbox( j, i, 1, 1, s->c) ;
- i++ ; y+= ody ;
- for( ; i <= s->ey; i++, y+= ody ) {
- gl_fillbox( j, i, 1, 1, steps( x, y, 255 ) ) ;
- }
- j++ ; x+= odx ;
- for( ; j <= s->ex; j++, x+= odx)
- for( i=s->sy,y=init_y; i<=s->ey; i++,y+=ody) {
- gl_fillbox( j, i,1,1, steps(x,y,255)) ;
- }
- }
-
- int clean( sdata *s, double or_x, double or_y, double odx, double ody, int *counter, NXColor *p, int resolution, int use_fixed )
- {
- double x, y, init_x, init_y ;
- int i,j, hx1, hy1, hx2, hy2, cur, cur2 ;
-
- x = or_x + s->sx * odx ;
- y = or_y + s->sy * ody ;
- if( (s->ex - s->sx) < 3 ) {
- init_x = x ; init_y = y ;
- j = s->sx ; i=s->sy ;
- gl_fillbox( j, i, 1, 1, s->c) ;
- i++ ; y+= ody ;
- for( ; i <= s->ey; i++, y+= ody ) {
- gl_fillbox( j, i, 1, 1, steps( x, y, 255 ) ) ;
- }
- j++ ; x+= odx ;
- for( ; j <= s->ex; j++, x+= odx)
- for( i=s->sy,y=init_y; i<=s->ey; i++,y+=ody) {
- gl_fillbox( j, i,1,1, steps(x,y,255)) ;
- }
- return TRUE ;
- } else if( (s->ey - s->sy) < 3 ) {
- init_x = x ; init_y = y ;
- j = s->sx ; i=s->sy ;
- gl_fillbox( j, i, 1, 1, s->c) ;
- j++ ; x+= odx ;
- for( ; j <= s->ex; j++, x+= odx ) {
- gl_fillbox( j, i, 1, 1, steps( x, y, 255 ) ) ;
- }
- i++ ; y+= ody ;
- for( ; i <= s->ey; i++, y+= ody)
- for( j=s->sx, x=init_x ; j<=s->ex; j++,x+=odx) {
- gl_fillbox( j, i,1,1, steps(x,y,255)) ;
- }
- return TRUE ;
- }
-
- hx1 = (s->ex - s->sx) >> 1 ;
- hy1 = (s->ey - s->sy) >> 1 ;
-
-
- if( hx1 == 0 ) hx1 = 1 ;
- if( hy1 == 0 ) hy1 = 1 ;
-
- hx2 = s->ex - s->sx - hx1 ;
- hy2 = s->ey - s->sy - hy1 ;
-
-
-
- cur = s[0].c ;
- s[1].c = steps( x + hx1 *odx, y,255) ;
- s[2].c = steps( x + hx1 *odx, y + hy1 * ody,255 ) ;
- s[3].c = steps( x , y + hy1 * ody,255 ) ;
-
- gl_fillbox( s->sx, s->sy, hx1, hy1, cur ) ;
- gl_fillbox( s->sx + hx1, s->sy, hx2+1, hy1, s[1].c ) ;
- gl_fillbox( s->ex - hx2, s->sy+hy1, hx2+1, hy2+1, s[2].c ) ;
- gl_fillbox( s->sx, s->ey-hy2, hx1, hy2+1, s[3].c ) ;
-
- if( (s[1].c != cur) || (s[2].c != cur) || (s[3].c != cur))
- return FALSE ;
-
-
- /** - */
- j = s->sy ;
- for( i=s->sx+1, x+=odx ; i<s->sx+hx1; i++, x+= odx ) {
- cur2 = steps( x,y,curp1 ) ;
- if( cur != cur2 )
- return FALSE ;
- }
- cur2 = steps( x, y, curp1) ;
- if( cur != cur2 )
- return FALSE ;
- /** -- */
- for( i++, x+=odx ; i <= s->ex; i++, x+= odx ) {
- cur2 = steps( x, y, curp1) ;
- if( cur != cur2 )
- return FALSE ;
- }
-
- x -= odx ;
- i-- ;
- /** --| */
- for( j=s->sy ; j < s->sy+hy1; j++, y+= ody ) {
- cur2 = steps( x, y, curp1 ) ;
- if( cur != cur2 )
- return FALSE ;
- }
- cur2 = steps( x, y, curp1) ;
- if( cur != cur2 )
- return FALSE ;
- /** --|
- | */
- for( j++, y+= ody ; j <= s->ey; j++, y+= ody ) {
- cur2 = steps( x, y, curp1 ) ;
- if( cur != cur2 )
- return FALSE ;
- }
- /** --|
- -| */
- y -= ody ;
- j-- ;
- for( i=s->ex ; i >= s->sx+hx1; i--, x-= odx ) {
- cur2 = steps( x, y, curp1 ) ;
- if( cur != cur2 )
- return FALSE ;
- }
-
- cur2 = steps( x, y, curp1) ;
- if( cur != cur2 )
- return FALSE ;
- /** --|
- --| */
- for( i--, x-= odx ; i >= s->sx; i--, x-= odx ) {
- cur2 = steps( x, y, curp1 ) ;
- if( cur != cur2 )
- return FALSE ;
- }
- /** --|
- |--| */
- x += odx ;
- i++ ;
- for( j=s->ey ; j >= s->sy+hy1; j--, y-= ody ) {
- cur2 = steps( x, y, curp1) ;
- if( cur != cur2 )
- return FALSE ;
- }
- /** |--|
- |--| */
- for( ; j >= s->sy ; j--, y-= ody ) {
- cur2 = steps( x, y, curp1 ) ;
- if( cur != cur2 )
- return FALSE ;
- }
- return TRUE ;
- }
-
-
-
-
-
- void sort( sdata *s, int n, int depth )
- {
- sdata t ;
- int i, mi ;
- mi = 0 ;
- if( n > 0 ) {
- for( i= (n > depth) ? n-depth:0; i <= n; i++)
- if( s[i].c < s[mi].c)
- mi = i ;
- if( mi != n ) { t = s[mi]; s[mi] = s[n]; s[n] = t ; }
- }
- }
-
- -oneStep
- {
- double temp ;
- sdata *ctodo ;
- int counter, hx, hy ;
- if( !drawing_mandel ) {
- if( time(NULL) - last_finished > 4 ) {
- drawing_mandel = TRUE ;
- }
- else if( !frame_drawn ) {
- if( time(NULL) - last_finished > 2 )
- [self drawNextBounds] ;
- }
- return self ;
- }
-
-
- ctodo = todo+stack ;
- counter = 0 ;
- while( (counter < 10) && (stack > -1) && (stack < 990) ) {
- counter++ ;
- ctodo = todo+stack ;
- if( !clean( &todo[stack], or_x, or_y, odx, ody, &counter, mypal, resolution, use_fixed ) ) {
- draw_length++ ;
- hx = (ctodo->ex - ctodo->sx) / 2 ;
- hy = (ctodo->ey - ctodo->sy) / 2 ;
- if( hx == 0 ) hx = 1 ;
- if( hy == 0 ) hy = 1 ;
-
-
- todo[stack+1].sx = ctodo->sx + hx ;
- todo[stack+1].sy = ctodo->sy ;
- todo[stack+1].ex = ctodo->ex ;
- todo[stack+1].ey = ctodo->sy + hy -1 ;
-
- todo[stack+3].sx = ctodo->sx ;
- todo[stack+3].sy = ctodo->sy + hy ;
- todo[stack+3].ex = ctodo->sx + hx -1 ;
- todo[stack+3].ey = ctodo->ey ;
-
-
- todo[stack+2].sx = ctodo->sx + hx ;
- todo[stack+2].sy = ctodo->sy + hy ;
- todo[stack+2].ex = ctodo->ex ;
- todo[stack+2].ey = ctodo->ey ;
-
- todo[stack].sx = ctodo->sx ;
- todo[stack].sy = ctodo->sy ;
- todo[stack].ex = ctodo->sx + hx -1 ;
- todo[stack].ey = ctodo->sy + hy -1 ;
-
- stack+=3 ;
- if( stack > max_stack )
- max_stack = stack ;
-
- sort( todo, stack, 6 ) ;
- } else {
- stack-- ;
- sort( todo, stack, 100 ) ;
- }
- }
- if( stack >= 990 ) {
- just_do( &todo[stack], or_x, or_y, odx, ody, &counter, mypal, resolution, use_fixed ) ;
- stack-- ;
- }
- if( stack < 0 ) {
-
- old_or_x = or_x ;old_or_y = or_y ;
- old_or_w = or_w ;
- last_finished = time(NULL) ;
- drawing_mandel = FALSE ;
- frame_drawn = FALSE ;
-
-
- if( best_draw_length == 0 )
- best_draw_length = draw_length ;
-
-
- if( draw_length < best_draw_length / 2 ) {
- drawing_mandel = TRUE ;
- if( best_lost == 20 ) {
- or_w = 2.5 ;
- or_x = -2.0 ;
- or_y = -1.25 ;
- } else {
- or_x = best_or_x ;
- or_y = best_or_y ;
- or_w = best_or_w ;
- best_lost++ ;
- }
- } else {
- best_lost = 0 ;
- best_or_x = or_x ;
- best_or_y = or_y ;
- best_or_w = or_w ;
- }
-
- or_x = 0.01 * (random() % 100) * or_w + or_x ;
- or_y = 0.01 * (random() % 100) * or_w + or_y ;
- or_w /= 5.0 ;
-
-
-
- odx = or_w / bounds.size.width ;
- ody = odx ;
- temp = or_x + odx ;
-
- if( double_to_fixed( temp ) == double_to_fixed( or_x ) )
- use_fixed = FALSE ;
- else
- use_fixed = TRUE ;
-
- stack = 0 ;
- todo[0].sx = 0 ;
- todo[0].ex = bounds.size.width-1 ;
- todo[0].sy = 0 ;
- todo[0].ey = bounds.size.height-1 ;
- todo[0].c = steps( or_x, or_y, 255 ) ;
- max_stack = 0 ;
- draw_length = 0 ;
- }
- return self ;
- }
-
- - drawNextBounds
- {
- double oo_pixelwidth ;
- int x, y, w, h ;
- NXRect myrect2 ;
-
- oo_pixelwidth = (double) bounds.size.width / old_or_w ;
- x = (or_x - old_or_x) * oo_pixelwidth ;
- y = (or_y - old_or_y) * oo_pixelwidth ;
- w = or_w * bounds.size.width / old_or_w ;
- h = or_w * bounds.size.height / old_or_w ;
- NXSetColor( NXConvertRGBToColor( (float) 0.8, (float)0.8, (float)0.8 )) ;
- NXSetRect( &myrect2, x, y, w, h ) ;
- NXFrameRect( &myrect2) ;
-
- frame_drawn = TRUE ;
- return self ;
- }
-
- static float randMod(float orig, float by, float min, float max)
- {
- orig = orig + RANDFLOAT(by * 2.0) - by;
- return (orig < min) ? min : ((orig > max) ? max : orig);
- }
-
- - newWindow
- {
-
- or_w = 2.5 ;
-
- odx = or_w / bounds.size.width ;
- ody = odx ;
-
- or_x = -2.0 ;
- or_y = -1.25 ;
-
-
-
- stack = 0 ; max_stack = 0 ;
- todo[0].sx = 0 ;
- todo[0].ex = bounds.size.width-1 ;
- todo[0].sy = 0 ;
- todo[0].ey = bounds.size.height-1 ;
- todo[0].c = steps( or_x, or_y, 255 ) ;
-
- best_lost = 0 ;
- best_max_stack = 0 ;
- draw_length = 0 ;
- best_draw_length = 0 ;
-
- return self;
- }
-
- - free
- {
- return [super free];
- }
-
- - setImage: image
- {
- return self;
- }
-
- - sizeTo:(NXCoord)width :(NXCoord)height
- {
- [super sizeTo:width :height];
-
- if (!alreadyInitialized)
- {
- alreadyInitialized = YES;
- }
-
- [self newWindow];
- return self;
- }
-
- - inspector:sender
- {
- char buf[MAXPATHLEN];
-
- if (!inspectorPanel)
- {
- [NXBundle getPath:buf forResource:"mandle" ofType:"nib" inDirectory:[sender moduleDirectory:"Mandel"] withVersion:0];
- [NXApp loadNibFile:buf owner:self withNames:NO];
-
- }
- drawing_mandel = TRUE ;
- frame_drawn = TRUE ;
- use_fixed = TRUE ;
- [self setColors:backWell ] ;
- return inspectorPanel;
- }
-
- - setLineWidth:sender
- {
- return self;
- }
-
- - setNumLines:sender
- {
- return self;
- }
-
- - setUseColor:sender
- {
- return self;
- }
-
- - giveColorPanel:sender
- {
- [NXColorPanel sharedInstance:YES];
- [NXApp orderFrontColorPanel:NXApp];
- return self ;
- }
-
- @end
-