home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Apps / ScreenSavers / BackSpaceViews / MandelView.BackModule / MandelView.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  14.9 KB  |  651 lines

  1.  
  2. #import "MandelView.h"
  3. #import "Thinker.h"
  4.  
  5. #include "ms_real.h"
  6. #include "ms_real.c"
  7. //
  8. #include "time.h"
  9.  
  10. //#define steps(a,b,c) mandelbrot(a,b,256)
  11. #define steps(a,b,c) (use_fixed ? mandelbrot(a,b,256) : newsteps(a,b) )
  12. #define RANDINT(n) (random() % (n))
  13. #define RANDFLOAT(f) (((f) * (float)(random() & 0x0ffff)) / (float)0x0ffff)
  14.  
  15. int newsteps( double x, double y) ;
  16.      
  17.  
  18.  
  19. @implementation MandelView
  20.  
  21. void spreadNXColors( NXColor col1, NXColor col2, NXColor *targ, int n ) 
  22. {
  23.     float cur_rgb[3], rgb_step[3] ;
  24.     int i ;
  25.  
  26.     NXConvertColorToRGB( col2, &(rgb_step[0]), &(rgb_step[1]), &(rgb_step[2]) ) ;
  27.     NXConvertColorToRGB( col1, &(cur_rgb[0]), &(cur_rgb[1]), &(cur_rgb[2]) ) ;
  28.     
  29.     rgb_step[0] -= cur_rgb[0] ;
  30.     rgb_step[1] -= cur_rgb[1] ;
  31.     rgb_step[2] -= cur_rgb[2] ;
  32.  
  33.     rgb_step[0] /= (n-1) ;
  34.     rgb_step[1] /= (n-1) ;
  35.     rgb_step[2] /= (n-1) ;
  36.  
  37.     for( i=0; i<n; i++) {
  38.     targ[i] = NXConvertRGBToColor( cur_rgb[0], cur_rgb[1], cur_rgb[2] ) ;
  39.     cur_rgb[0] += rgb_step[0] ;
  40.     cur_rgb[1] += rgb_step[1] ;
  41.     cur_rgb[2] += rgb_step[2] ;
  42.     }
  43. }
  44.  
  45. int newsteps( double x, double y)
  46. {
  47.     register double x1, y1, xs, ys ;
  48.     register int c;
  49.  
  50.     x1 = x ; y1 = y ;
  51.  
  52.     xs = x1 * x1 ;
  53.     ys = y1 * y1 ;
  54.     c = 0 ;
  55.     while( (xs + ys < 4.0) && (c < 255) ) {
  56.     y1 = 2 * x1 * y1 + y ;
  57.     x1 = xs - ys + x ;
  58.     c++ ;
  59.     xs = x1 * x1 ;
  60.     ys = y1 * y1 ;
  61.     }
  62.     return c ;
  63. }
  64.  
  65. /* this routine was taken from mandelspawn 0.7 by Andreas Gustafsson,
  66. gson@niksula.hut.fi */
  67.  
  68. /*  
  69.     This file is part of MandelSpawn, a network Mandelbrot program.
  70.  
  71.     Copyright (C) 1990-1993 Andreas Gustafsson
  72.  
  73.     MandelSpawn is free software; you can redistribute it and/or modify
  74.     it under the terms of the GNU General Public License, version 1,
  75.     as published by the Free Software Foundation.
  76.  
  77.     MandelSpawn is distributed in the hope that it will be useful,
  78.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  79.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  80.     GNU General Public License for more details.
  81.  
  82.     You should have received a copy of the GNU General Public License,
  83.     version 1, along with this program; if not, write to the Free 
  84.     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  85. */
  86.  
  87. int mandelbrot(parms0, parms1, maxiter )
  88.     double parms0,parms1;
  89.     int maxiter;
  90. {
  91.       register real x_re, x_im;
  92.       register real c_re, c_im;
  93.       register real xresq, ximsq;
  94.  
  95.       int count;
  96.  
  97.  
  98.       c_re = double_to_fixed(parms0);
  99.       c_im = double_to_fixed(parms1);
  100.       x_re = c_re ;
  101.       x_im = c_im ;
  102.  
  103.       /* The following loop is where the Real Work gets done. */
  104.       count=0;
  105.       while(count < 255)
  106.       {    
  107.     /* 
  108.       This is the familiar "z := z^2 + c; abort if |z| > 2"
  109.       Mandelbrot iteration, with the arithmetic operators hidden
  110.       in macros so that the same code can be compiled for either
  111.       fixed-point or floating-point arithmetic.
  112.       The macros (mul_real(), etc.) are defined in ms_real.h. 
  113.     */
  114.     xresq=mul_real(x_re, x_re);
  115.     ximsq=mul_real(x_im, x_im);
  116.     if(gteq_real(add_real(xresq, ximsq), four_real()))
  117.       break;
  118.     x_im=add_real(twice_mul_real(x_re, x_im), c_im);
  119.     x_re=add_real(sub_real(xresq, ximsq), c_re);
  120.     count++;
  121.       }
  122.   return count;
  123. }
  124.  
  125. - initFrame:(NXRect *)rect
  126. {
  127.  
  128.     sx = -1.5 ; ex = 1.0 ;
  129.     sy = -1.5 ; ey = 1.5 ;
  130.  
  131.     [super initFrame:rect];
  132.  
  133.     [self allocateGState];        // For faster lock/unlockFocus
  134.     
  135.     [inspectorPanel display];
  136.  
  137.     color = NX_COLORYELLOW;
  138.     alreadyInitialized = NO;
  139.     randCount1 = 100;
  140.     randCount2 = 200;
  141.  
  142.     drawing_mandel = TRUE ;
  143.     frame_drawn = TRUE ;
  144.     use_fixed = TRUE ;
  145.     [self setColors:backWell ] ;
  146.     
  147.     
  148.     
  149.     or_w = 2.5 ;
  150.  
  151.     odx = or_w / bounds.size.width ;
  152.     ody = odx ;
  153.     
  154.     or_x = -2.0 ;
  155.     or_y = -1.25 ;
  156.  
  157.     best_lost = 0 ;
  158.     best_max_stack = 0 ;
  159.     best_draw_length = 0 ;
  160.     draw_length = 0 ;
  161.  
  162.     stack = 0 ;
  163.     todo[0].sx = 0 ;
  164.     todo[0].ex = bounds.size.width ;
  165.     todo[0].sy = 0 ;
  166.     todo[0].ey = bounds.size.height ;
  167.     todo[0].c = steps( or_x, or_y, 255 ) ;
  168.  
  169.     return self;
  170. }
  171.  
  172. - drawSelf:(const NXRect *)rects :(int)rectCount
  173. {
  174.     if (!rects || !rectCount) return self;
  175.     [super drawSelf:rects :rectCount];
  176.     return self;
  177. }
  178.  
  179. - setColors:sender
  180. {
  181.     mypal[255] = [backWell color] ;
  182.  
  183.     spreadNXColors( [Well1 color], [Well2 color], &(mypal[0]), 83 ) ;
  184.     spreadNXColors( [Well2 color], [Well3 color], &(mypal[83]), 83 ) ;
  185.     spreadNXColors( [Well3 color], [Well4 color], &(mypal[166]), 89  ) ;
  186.  
  187.     spreadNXColors( [Well1 color], [Well2 color], &(mypal[0]), 16 ) ;
  188.     spreadNXColors( [Well2 color], [Well3 color], &(mypal[16]), 16 ) ;
  189.     spreadNXColors( [Well3 color], [Well4 color], &(mypal[32]), 16 ) ;
  190.     spreadNXColors( [Well4 color], [Well1 color], &(mypal[48]), 16 ) ;
  191.     spreadNXColors( [Well1 color], [Well2 color], &(mypal[64]), 16 ) ;
  192.     spreadNXColors( [Well2 color], [Well3 color], &(mypal[80]), 16 ) ;
  193.     spreadNXColors( [Well3 color], [Well4 color], &(mypal[96]), 16 ) ;
  194.     spreadNXColors( [Well4 color], [Well1 color], &(mypal[112]), 16 ) ;
  195.     spreadNXColors( [Well1 color], [Well2 color], &(mypal[128]), 16 ) ;
  196.     spreadNXColors( [Well2 color], [Well3 color], &(mypal[128+0]), 16 ) ;
  197.     spreadNXColors( [Well3 color], [Well4 color], &(mypal[128+16]), 16 ) ;
  198.     spreadNXColors( [Well4 color], [Well1 color], &(mypal[128+32]), 16 ) ;
  199.     spreadNXColors( [Well1 color], [Well2 color], &(mypal[128+48]), 16 ) ;
  200.     spreadNXColors( [Well2 color], [Well3 color], &(mypal[128+64]), 16 ) ;
  201.     spreadNXColors( [Well3 color], [Well4 color], &(mypal[128+80]), 16 ) ;
  202.     spreadNXColors( [Well4 color], [Well1 color], &(mypal[128+96]), 16 ) ;
  203.     spreadNXColors( [Well1 color], [Well2 color], &(mypal[128+112]), 15 ) ;
  204.  
  205.     return self ;
  206. }
  207.  
  208. - setImageConstraints
  209. {
  210.     [super setImageConstraints];
  211.  
  212.     if (imageRect.origin.x > maxCoord.x ||
  213.         imageRect.origin.y > maxCoord.y)
  214.     {
  215.         imageRect.origin.x = randBetween(0, maxCoord.x);
  216.         imageRect.origin.y = randBetween(0, maxCoord.y);
  217.     }
  218.  
  219.     return self;
  220. }
  221.  
  222.  
  223. #define gl_fillbox( x, y, h, w, c ) myfillbox( x, y, h, w, c,p )
  224.  
  225. #define gl_setpixel(a, b, c)
  226.  
  227. void myfillbox( int x, int y, int w, int h, int c, NXColor *p )
  228. {
  229.     NXRect myrect2 ;
  230. //    NXSetColor( NXConvertRGBToColor( (float) (c%17) / 17, (float)(c%39) / 39, 1-(float)(c%64)/64.0 )) ;
  231.     NXSetColor( p[c] ) ;
  232.     NXSetRect( &myrect2, x, y, w, h ) ;
  233.     NXRectFill( &myrect2) ;
  234. }
  235.  
  236. void just_do( sdata *s, double or_x, double or_y, double odx, double ody, int *counter, NXColor *p, int resolution, int use_fixed )
  237. {
  238.     double x, y, init_x, init_y ;
  239.     int i,j ;
  240.     
  241.     x = or_x + s->sx * odx ;
  242.     y = or_y + s->sy * ody ;
  243.     init_x = x ; init_y = y ;
  244.     j = s->sx ; i=s->sy ; 
  245.     gl_fillbox( j, i, 1, 1, s->c) ;
  246.     i++ ; y+= ody ;
  247.     for( ; i <= s->ey; i++, y+= ody ) {
  248.     gl_fillbox( j, i, 1, 1, steps( x, y, 255 ) ) ;
  249.     }
  250.     j++ ; x+= odx ;
  251.     for( ; j <= s->ex; j++, x+= odx) 
  252.     for( i=s->sy,y=init_y; i<=s->ey; i++,y+=ody) {
  253.         gl_fillbox( j, i,1,1, steps(x,y,255)) ;
  254.     }
  255. }
  256.  
  257. int clean( sdata *s, double or_x, double or_y, double odx, double ody, int *counter, NXColor *p, int resolution, int use_fixed )
  258. {
  259.     double x, y, init_x, init_y ;
  260.     int i,j, hx1, hy1, hx2, hy2, cur, cur2 ;
  261.     
  262.     x = or_x + s->sx * odx ;
  263.     y = or_y + s->sy * ody ;
  264.     if( (s->ex - s->sx) < 3 ) {
  265.     init_x = x ; init_y = y ;
  266.     j = s->sx ; i=s->sy ; 
  267.     gl_fillbox( j, i, 1, 1, s->c) ;
  268.     i++ ; y+= ody ;
  269.     for( ; i <= s->ey; i++, y+= ody ) {
  270.         gl_fillbox( j, i, 1, 1, steps( x, y, 255 ) ) ;
  271.     }
  272.     j++ ; x+= odx ;
  273.     for( ; j <= s->ex; j++, x+= odx) 
  274.         for( i=s->sy,y=init_y; i<=s->ey; i++,y+=ody) {
  275.         gl_fillbox( j, i,1,1, steps(x,y,255)) ;
  276.         }
  277.     return TRUE ;
  278.     } else if( (s->ey - s->sy) < 3 ) {
  279.     init_x = x ; init_y = y ;
  280.     j = s->sx ; i=s->sy ; 
  281.     gl_fillbox( j, i, 1, 1, s->c) ;
  282.     j++ ; x+= odx ;
  283.     for( ; j <= s->ex; j++, x+= odx ) {
  284.         gl_fillbox( j, i, 1, 1, steps( x, y, 255 ) ) ;
  285.     }
  286.     i++ ; y+= ody ;
  287.     for( ; i <= s->ey; i++, y+= ody) 
  288.         for( j=s->sx, x=init_x ; j<=s->ex; j++,x+=odx) {
  289.         gl_fillbox( j, i,1,1, steps(x,y,255)) ;
  290.         }
  291.     return TRUE ;
  292.     }
  293.  
  294.     hx1 = (s->ex - s->sx) >> 1  ;
  295.     hy1 = (s->ey - s->sy) >> 1 ;
  296.  
  297.  
  298.     if( hx1 == 0 ) hx1 = 1 ;
  299.     if( hy1 == 0 ) hy1 = 1 ;
  300.  
  301.     hx2 = s->ex - s->sx - hx1  ;
  302.     hy2 = s->ey - s->sy - hy1  ;
  303.  
  304.     
  305.  
  306.     cur = s[0].c ;
  307.     s[1].c = steps( x + hx1 *odx, y,255) ;
  308.     s[2].c = steps( x + hx1 *odx, y + hy1 * ody,255 ) ;
  309.     s[3].c = steps( x , y + hy1 * ody,255 ) ;
  310.     
  311.     gl_fillbox( s->sx, s->sy, hx1, hy1, cur ) ;
  312.     gl_fillbox( s->sx + hx1, s->sy, hx2+1, hy1, s[1].c ) ;
  313.     gl_fillbox( s->ex - hx2, s->sy+hy1, hx2+1, hy2+1, s[2].c ) ;
  314.     gl_fillbox( s->sx, s->ey-hy2, hx1, hy2+1, s[3].c ) ;
  315.  
  316.     if( (s[1].c != cur) || (s[2].c != cur) || (s[3].c != cur))
  317.     return FALSE ;
  318.  
  319.     
  320. /** - */
  321.     j = s->sy ;
  322.     for( i=s->sx+1, x+=odx ; i<s->sx+hx1; i++, x+= odx )  {
  323.     cur2 = steps( x,y,curp1 ) ;
  324.     if( cur != cur2 ) 
  325.         return FALSE ;
  326.     }
  327.     cur2 = steps( x, y, curp1) ;
  328.     if( cur != cur2 )
  329.     return FALSE ;
  330. /** -- */
  331.     for( i++, x+=odx ; i <= s->ex; i++, x+= odx )  {
  332.     cur2 = steps( x, y, curp1) ;
  333.     if( cur != cur2 )
  334.         return FALSE ;
  335.     }
  336.  
  337.     x -= odx ;
  338.     i-- ;
  339. /** --| */
  340.     for( j=s->sy ; j < s->sy+hy1; j++, y+= ody ) {
  341.     cur2 = steps( x, y, curp1 ) ;
  342.     if( cur != cur2 )
  343.         return FALSE ;
  344.     }
  345.     cur2 = steps( x, y, curp1) ;
  346.     if( cur != cur2 )
  347.     return FALSE ;
  348. /** --|
  349.       | */
  350.     for( j++, y+= ody ; j <= s->ey; j++, y+= ody ) {
  351.     cur2 = steps( x, y, curp1 ) ;
  352.     if( cur != cur2 )
  353.         return FALSE ;
  354.     }
  355. /** --|
  356.      -| */
  357.     y -= ody ;
  358.     j-- ;
  359.     for( i=s->ex ; i >= s->sx+hx1; i--, x-= odx ) {
  360.     cur2 = steps( x, y, curp1 ) ;
  361.     if( cur != cur2 )
  362.         return FALSE ;
  363.     }
  364.  
  365.     cur2 = steps( x, y, curp1) ;
  366.     if( cur != cur2 )
  367.     return FALSE ;
  368. /** --|
  369.     --| */
  370.     for( i--, x-= odx ; i >= s->sx; i--, x-= odx ) {
  371.     cur2 = steps( x, y, curp1 ) ;
  372.     if( cur != cur2 )
  373.         return FALSE ;
  374.     }
  375. /** --|
  376.    |--| */
  377.     x += odx ;
  378.     i++ ;
  379.     for( j=s->ey ; j >= s->sy+hy1; j--, y-= ody ) {
  380.     cur2 = steps( x, y, curp1) ;
  381.     if( cur != cur2 )
  382.         return FALSE ;
  383.     }
  384. /** |--|
  385.     |--| */
  386.     for( ; j >= s->sy ; j--, y-= ody ) {
  387.     cur2 = steps( x, y, curp1 ) ;
  388.     if( cur != cur2 )
  389.         return FALSE ;
  390.     }
  391.     return TRUE ;
  392. }
  393.  
  394.  
  395.  
  396.  
  397.  
  398. void sort( sdata *s, int n, int depth )
  399. {
  400.     sdata t ;
  401.     int i, mi ;
  402.     mi = 0 ;
  403.     if( n > 0 ) {
  404.     for( i= (n > depth) ? n-depth:0; i <= n; i++)
  405.         if( s[i].c < s[mi].c)
  406.         mi = i ;
  407.     if( mi != n ) { t = s[mi]; s[mi] = s[n]; s[n] = t ; }
  408.     }
  409. }
  410.  
  411. -oneStep
  412. {
  413.     double temp ;
  414.     sdata *ctodo ;
  415.     int counter, hx, hy ;
  416.     if( !drawing_mandel ) {
  417.     if( time(NULL) - last_finished > 4 ) {
  418.         drawing_mandel = TRUE ;
  419.     }
  420.     else if( !frame_drawn ) {
  421.         if( time(NULL) - last_finished > 2 ) 
  422.         [self drawNextBounds] ;
  423.     }
  424.     return self ;
  425.     }
  426.  
  427.  
  428.     ctodo = todo+stack ;
  429.     counter = 0 ;
  430.     while( (counter < 10) && (stack > -1) && (stack < 990) ) {
  431.     counter++ ;
  432.     ctodo = todo+stack ;
  433.     if( !clean( &todo[stack], or_x, or_y, odx, ody, &counter, mypal, resolution, use_fixed ) ) {
  434.         draw_length++ ;
  435.         hx = (ctodo->ex - ctodo->sx) / 2 ;
  436.         hy = (ctodo->ey - ctodo->sy) / 2 ;
  437.         if( hx == 0 ) hx = 1 ;
  438.         if( hy == 0 ) hy = 1 ;
  439.         
  440.         
  441.         todo[stack+1].sx = ctodo->sx + hx ;
  442.         todo[stack+1].sy = ctodo->sy ;
  443.         todo[stack+1].ex = ctodo->ex ;
  444.         todo[stack+1].ey = ctodo->sy + hy -1 ;
  445.  
  446.         todo[stack+3].sx = ctodo->sx ;
  447.         todo[stack+3].sy = ctodo->sy + hy ;
  448.         todo[stack+3].ex = ctodo->sx + hx -1 ;
  449.         todo[stack+3].ey = ctodo->ey ;
  450.  
  451.  
  452.         todo[stack+2].sx = ctodo->sx + hx ;
  453.         todo[stack+2].sy = ctodo->sy + hy ;
  454.         todo[stack+2].ex = ctodo->ex ;
  455.         todo[stack+2].ey = ctodo->ey ;
  456.  
  457.         todo[stack].sx = ctodo->sx ;
  458.         todo[stack].sy = ctodo->sy ;
  459.         todo[stack].ex = ctodo->sx + hx -1 ;
  460.         todo[stack].ey = ctodo->sy + hy -1 ;
  461.  
  462.         stack+=3 ;
  463.         if( stack > max_stack )
  464.         max_stack = stack ;
  465.  
  466.         sort( todo, stack,  6 ) ;
  467.     } else {
  468.         stack-- ;
  469.         sort( todo, stack, 100 ) ;
  470.     }
  471.     }
  472.     if( stack >= 990 ) {
  473.     just_do( &todo[stack], or_x, or_y, odx, ody, &counter, mypal, resolution, use_fixed ) ;
  474.     stack-- ;
  475.     }
  476.     if( stack < 0 ) {
  477.  
  478.     old_or_x = or_x ;old_or_y = or_y ;
  479.     old_or_w = or_w ;
  480.     last_finished = time(NULL) ;
  481.     drawing_mandel = FALSE ;
  482.     frame_drawn = FALSE ;
  483.  
  484.  
  485.     if( best_draw_length == 0 )
  486.         best_draw_length = draw_length ;
  487.     
  488.  
  489.     if( draw_length < best_draw_length / 2 ) {
  490.         drawing_mandel = TRUE ;
  491.         if( best_lost == 20 ) {
  492.         or_w = 2.5 ;
  493.         or_x = -2.0 ;
  494.         or_y = -1.25 ;
  495.         } else {
  496.         or_x = best_or_x ;
  497.         or_y = best_or_y ;
  498.         or_w = best_or_w ;
  499.         best_lost++ ;
  500.         }
  501.     } else {
  502.         best_lost = 0 ;
  503.         best_or_x = or_x ;
  504.         best_or_y = or_y ;
  505.         best_or_w = or_w ;
  506.     }
  507.  
  508.     or_x = 0.01 * (random() % 100) * or_w + or_x ;
  509.     or_y = 0.01 * (random() % 100) * or_w + or_y ;
  510.     or_w /= 5.0 ;
  511.  
  512.  
  513.  
  514.     odx = or_w / bounds.size.width ;
  515.     ody = odx ;
  516.     temp = or_x + odx ;
  517.  
  518.            if( double_to_fixed( temp ) == double_to_fixed( or_x ) )
  519.         use_fixed = FALSE ;
  520.     else
  521.         use_fixed = TRUE ;
  522.  
  523.     stack = 0 ;
  524.     todo[0].sx = 0 ;
  525.     todo[0].ex = bounds.size.width-1 ;
  526.     todo[0].sy = 0 ;
  527.     todo[0].ey = bounds.size.height-1 ;
  528.     todo[0].c = steps( or_x, or_y, 255 ) ;
  529.     max_stack = 0 ;
  530.     draw_length = 0 ;
  531.     }
  532.     return self ;
  533. }
  534.  
  535. - drawNextBounds
  536. {
  537.     double oo_pixelwidth ;
  538.     int x, y, w, h ;
  539.     NXRect myrect2 ;
  540.  
  541.     oo_pixelwidth = (double) bounds.size.width / old_or_w ; 
  542.     x = (or_x - old_or_x) * oo_pixelwidth ;
  543.     y = (or_y - old_or_y) * oo_pixelwidth ;
  544.     w = or_w * bounds.size.width / old_or_w ;
  545.     h = or_w * bounds.size.height / old_or_w ;
  546.     NXSetColor( NXConvertRGBToColor( (float) 0.8, (float)0.8, (float)0.8 )) ;
  547.     NXSetRect( &myrect2, x, y, w, h ) ;
  548.     NXFrameRect( &myrect2) ;
  549.    
  550.     frame_drawn = TRUE ;
  551.     return self ;
  552. }
  553.  
  554. static float randMod(float orig, float by, float min, float max)
  555.     orig = orig + RANDFLOAT(by * 2.0) - by;
  556.     return (orig < min) ? min : ((orig > max) ? max : orig);
  557. }
  558.  
  559. - newWindow
  560. {
  561.  
  562.     or_w = 2.5 ;
  563.  
  564.     odx = or_w / bounds.size.width ;
  565.     ody = odx ;
  566.  
  567.     or_x = -2.0 ;
  568.     or_y = -1.25 ;
  569.  
  570.  
  571.  
  572.     stack = 0 ; max_stack = 0 ;
  573.     todo[0].sx = 0 ;
  574.     todo[0].ex = bounds.size.width-1 ;
  575.     todo[0].sy = 0 ;
  576.     todo[0].ey = bounds.size.height-1 ;
  577.     todo[0].c = steps( or_x, or_y, 255 ) ;
  578.  
  579.     best_lost = 0 ;
  580.     best_max_stack = 0 ;
  581.     draw_length = 0 ;
  582.     best_draw_length = 0 ;
  583.  
  584.     return self;
  585. }
  586.  
  587. - free
  588. {
  589.     return [super free];
  590. }
  591.  
  592. - setImage: image
  593. {
  594.     return self;
  595. }
  596.  
  597. - sizeTo:(NXCoord)width :(NXCoord)height
  598. {
  599.     [super sizeTo:width :height];
  600.     
  601.     if (!alreadyInitialized)
  602.     {    
  603.         alreadyInitialized = YES;
  604.     }
  605.  
  606.     [self newWindow];
  607.     return self;
  608. }
  609.  
  610. - inspector:sender
  611. {
  612.     char buf[MAXPATHLEN];
  613.     
  614.     if (!inspectorPanel)
  615.     {
  616.         [NXBundle getPath:buf forResource:"mandle" ofType:"nib" inDirectory:[sender moduleDirectory:"Mandel"] withVersion:0];
  617.         [NXApp loadNibFile:buf owner:self withNames:NO];
  618.  
  619.     }
  620.     drawing_mandel = TRUE ;
  621.     frame_drawn = TRUE ;
  622.     use_fixed = TRUE ;
  623.     [self setColors:backWell ] ;
  624.     return inspectorPanel; 
  625. }
  626.  
  627. - setLineWidth:sender
  628. {
  629.     return self;
  630. }
  631.  
  632. - setNumLines:sender
  633. {
  634.     return self;
  635. }
  636.  
  637. - setUseColor:sender
  638. {
  639.     return self;
  640. }
  641.  
  642. - giveColorPanel:sender
  643. {
  644.     [NXColorPanel sharedInstance:YES];
  645.     [NXApp orderFrontColorPanel:NXApp];
  646.     return self ;
  647. }
  648.  
  649. @end
  650.