home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Educational / Julia / Source / DrawView.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  5.1 KB  |  234 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. #import "DrawView.h"
  5.  
  6. #define PRINTER_PIXEL_FACTOR 67.0        // dpi of screen when printed
  7. #define LINE_WIDTH_FACTOR 1.08            // fudge factor to avoid aliasing
  8.  
  9. @implementation DrawView
  10.  
  11. + newFrame: (NXRect *)rect  
  12. {
  13.     self = [super newFrame:rect]; 
  14.     [self initialValues];
  15.     return self; 
  16. }
  17.  
  18. - (PROC) initialValues
  19. {
  20.     xmax = 2.0;
  21.     xmin = -2.0;
  22.     ymax = 2.0;
  23.     ymin = -2.0;
  24.     xc = 0.0;
  25.     yc = 1.0;
  26.     iterates = 12;
  27.     large = 10.0;
  28.     running = NO;
  29.     pixelSize = 6;
  30.     colors = 7;
  31. }
  32.  
  33. - (BOOL) continue    // Ignores all mousedown events until Stop is pressed
  34. {
  35.     NXEvent    *peekedEvent;
  36.     
  37.     peekedEvent = [NXApp peekAndGetNextEvent:NX_MOUSEDOWNMASK];
  38.     if (peekedEvent IS NULL)
  39.         return YES;
  40.     else if (NXPointInRect(&(peekedEvent->location), &stopRect))
  41.     {
  42.         [stopButton highlight:YES];
  43.         running = NO;
  44.         [stopButton highlight:NO];
  45.         return NO;
  46.     }
  47.     else
  48.         return YES;
  49. }
  50.  
  51. - drawSelf: (NXRect *)rect : (int) count 
  52. {
  53.     NXRect  frameRect;
  54.     int p, q,                 // pixel coords
  55.         pmax, qmax,         // pixels in screen
  56.         pstart;                // start of line to draw
  57.     float x, y,                // actual coords
  58.         dx, dy,                // distance between pixels
  59.         oldCol, newCol,        // colours of adjacent pixels
  60.         printerDot,            // distance between printer dots 
  61.         lineWidth,            // width 1 on printer is PRINTER_PIXEL_FACTOR
  62.         qHeight;            // vertical position of line to be drawn
  63.  
  64.     NXEraseRect(&bounds);
  65.     if ((NXDrawingStatus IS NX_DRAWING) AND running)
  66.     {
  67.         [self getParams];
  68.         [self getFrame:&frameRect];
  69.         pmax = (int) frameRect.size.width;
  70.         qmax = (int) frameRect.size.height;
  71.         dx = (xmax - xmin)/pmax;
  72.         dy = (ymax - ymin)/qmax;
  73.         PSsetlinewidth(1.0);
  74.          for (q = 0, y = ymin; (q <= qmax) AND [self continue]; q++, y += dy)
  75.         {
  76.             for (p = 0, pstart = 0, x = xmin, oldCol = NX_WHITE;
  77.                                                     p <= pmax; p++, x += dx)
  78.             {
  79.                 newCol = [self pixelCol:x :y];
  80.                 if (newCol IS_NOT oldCol)
  81.                 {
  82.                     if (oldCol IS_NOT NX_WHITE)
  83.                         [self drawline:oldCol :pstart :(p-1) :q];
  84.                     pstart = p;
  85.                     oldCol = newCol;
  86.                 }
  87.             }
  88.             if (oldCol IS_NOT NX_WHITE)
  89.                 [self drawline:oldCol :pstart :p :q];
  90.             [window flushWindow];
  91.         }
  92.     }
  93.     else if (NXDrawingStatus IS NX_PRINTING)
  94.     {
  95.         [self getParams];
  96.         [self getFrame:&frameRect];
  97.         printerDot = PRINTER_PIXEL_FACTOR/ 
  98.                     atoi(NXGetDefaultValue("System", "PrinterResolution"));
  99.         lineWidth = printerDot*pixelSize;
  100.         pmax = (int) ((frameRect.size.width)/lineWidth);
  101.         qmax = (int) ((frameRect.size.height)/lineWidth);
  102.         dx = (xmax - xmin)/pmax;
  103.         dy = (ymax - ymin)/qmax;
  104.         if (pixelSize > 1)
  105.             PSsetlinewidth(lineWidth*LINE_WIDTH_FACTOR);
  106.         else
  107.             PSsetlinewidth(0);
  108.          for (q = 0, y = ymin; (q <= qmax); q++, y += dy)
  109.         {
  110.             qHeight = (q + 0.5)*lineWidth;
  111.             for (p = 0, pstart = 0, x = xmin, oldCol = NX_WHITE; p <= pmax;
  112.                     p++, x += dx)
  113.             {
  114.                 newCol = [self pixelCol:x :y];
  115.                 if (newCol IS_NOT oldCol)
  116.                 {
  117.                     if (oldCol IS_NOT NX_WHITE)
  118.                         [self drawline :oldCol :(pstart*lineWidth) 
  119.                                         :(p*lineWidth - printerDot) :qHeight];
  120.                     pstart = p;
  121.                     oldCol = newCol;
  122.                 }
  123.             }
  124.             if (oldCol IS_NOT NX_WHITE)
  125.                 [self drawline:oldCol :(pstart*lineWidth) :(p*lineWidth) :qHeight];
  126.             [window flushWindow];
  127.         }
  128.     }        
  129.     return self;
  130. }
  131.  
  132. - (PROC) drawline:(float) col :(float) p1 :(float) p2 :(float) q
  133. {
  134.     PSnewpath();
  135.     PSmoveto(p1, q);
  136.     PSlineto(p2, q);
  137.     PSsetgray(col);
  138.     PSstroke();
  139. }
  140.  
  141. - (float) pixelCol:(float) x :(float) y
  142. {
  143.     int power;
  144.     float xx, yy;
  145.  
  146.     xx = x*x;
  147.     yy = y*y;
  148.     power = 0;
  149.     while (((xx + yy) < large) AND (power < iterates))
  150.     {
  151.         ++power;
  152.         y = 2*x*y + yc;
  153.         x = xx - yy + xc;        // f(z) = z*z + c
  154.         xx = x*x;
  155.         yy = y*y;
  156.     }
  157.     if (power >= iterates)
  158.         return NX_BLACK;
  159.     else
  160.         return (1.0 + (power MOD (colors - 1)))/(colors - 1);
  161. }
  162.  
  163. - setParamsForm:anObject
  164. {
  165.     paramsForm = anObject;
  166.     [paramsForm setFloatValue:xc at:0];
  167.     [paramsForm setFloatValue:yc at:1];
  168.     [paramsForm setFloatValue:xmin at:2];
  169.     [paramsForm setFloatValue:ymin at:3];
  170.     [paramsForm setFloatValue:xmax at:4];
  171.     [paramsForm setFloatValue:ymax at:5];
  172.     [paramsForm setIntValue:iterates at:6];
  173.     [paramsForm setFloatValue:large at:7];
  174.     [paramsForm setIntValue:colors at:8];
  175.     return self;
  176. }
  177.  
  178. - setPopUpButton:anObject
  179. {
  180.   id aPopUp;
  181.  
  182.   popUpButton = anObject;
  183.   aPopUp = [PopUpList new];
  184.   [aPopUp addItem:"1 dot"];
  185.   [aPopUp addItem:"2x2 dots"];
  186.   [aPopUp addItem:"3x3 dots"];
  187.   [aPopUp addItem:"4x4 dots"];
  188.   [aPopUp addItem:"5x5 dots"];
  189.   [aPopUp addItem:"6x6 dots"];
  190.   [[aPopUp itemList] selectCellAt:pixelSize - 1:0];
  191.   NXAttachPopUpList(popUpButton, aPopUp);
  192.   [aPopUp setTarget:self];
  193.   [aPopUp setAction:@selector(pixelSize:)];
  194.   return self;
  195. }
  196.  
  197. - setStopButton:anObject
  198. {
  199.     stopButton = anObject;
  200.     [stopButton getFrame:&stopRect];
  201.     return self;
  202. }
  203.  
  204. - getParams
  205. {
  206.     xc = [paramsForm floatValueAt:0];
  207.     yc = [paramsForm floatValueAt:1];
  208.     xmin = [paramsForm floatValueAt:2];
  209.     ymin = [paramsForm floatValueAt:3];
  210.     xmax = [paramsForm floatValueAt:4];
  211.     ymax = [paramsForm floatValueAt:5];
  212.     iterates = [paramsForm intValueAt:6];
  213.     large = [paramsForm floatValueAt:7];
  214.        colors = [paramsForm intValueAt:8];
  215.     if (colors < 2) 
  216.         colors = 2;
  217.     return self;
  218. }
  219.  
  220. - start:sender
  221. {
  222.     running = YES;
  223.     [self display];
  224.     return self;
  225. }
  226.  
  227. - pixelSize:sender
  228. {
  229.     pixelSize = 1 + [sender selectedRow];
  230.     return self;
  231. }
  232.  
  233. @end
  234.