home *** CD-ROM | disk | FTP | other *** search
/ PSION CD 2 / PsionCDVol2.iso / Programs / 874 / Plotter.sis / drawplot.opp < prev    next >
Encoding:
Text File  |  2000-09-27  |  4.3 KB  |  182 lines

  1. // Plotting functions for Plotter
  2. // ⌐ 1999-2000 Glenn Strong <Glenn.Strong@cs.tcd.ie>
  3. // Issued under the GNU General Public license, version 2
  4.  
  5. // Plot the function given by f$ between 0 and Max
  6. EXTERNAL Graph_Pass:(f$)
  7.  
  8. // Generate the permutations of the functions to
  9. // plot. The number of ▒ symbols controls the number
  10. // of permutations.
  11. EXTERNAL PlotPerms:(p%,max%)
  12.  
  13. // The magic "plusminus" symbol.
  14. #define PLUSMINUS %▒
  15.  
  16. // Plot the function given by f$ between 0 and Max
  17. // f$ is the function (a copy of orig$). items%
  18. // lists the positions of magic characters like ▒
  19. PROC PlotFunction:(orig$)
  20.     GLOBAL f$(255), items%(255)
  21.     LOCAL i%, j%, c%
  22.     f$=orig$
  23.     i%=1
  24.     j%=1
  25.     // Note the positions of magic characters (like ▒)
  26.     DO
  27.         c%=PEEKB(ADDR(f$)+i%)
  28.         IF c% = PLUSMINUS
  29.             items%(j%)=i%
  30.             j%++
  31.         ENDIF
  32.         i%++
  33.     UNTIL i%=LEN(orig$)
  34.  
  35.     // If there were no magic characters then we can
  36.     // just plot the function. Otherwise we find the
  37.     // permutations of the string that are functions
  38.     IF j%=1
  39.         GRAPH_PASS:(f$)
  40.     ELSE
  41.         PlotPerms:(1,j%)
  42.     ENDIF        
  43. ENDP
  44.  
  45. // Pass through the function in f$: generate & plot
  46. // the functions
  47. PROC PlotPerms:(p%,max%)
  48.     EXTERNAL f$, items%()
  49.  
  50.     // Base case for recursion
  51.     IF p%=max% : RETURN : ENDIF
  52.  
  53.     // Sub in a + sign for ▒.    
  54.     IF p%=1 OR (p%>1 AND (PEEKB(ADDR(f$)+p%)=%( ))
  55.         POKEB ADDR(f$)+items%(p%),32 // unary + messes up
  56.     ELSE    
  57.         POKEB ADDR(f$)+items%(p%),%+
  58.     ENDIF
  59.     PlotPerms:(p%+1,max%)
  60.     GRAPH_PASS:(f$)
  61.  
  62.     // Sub in a - sign for ▒.    
  63.     POKEB ADDR(f$)+items%(p%),%-
  64.     PlotPerms:(p%+1,max%)
  65.     GRAPH_PASS:(f$)
  66. ENDP
  67.  
  68. // Draw the function in f$ within the bounds set by
  69. // the global options. OPL's EVAL statement is used to
  70. // actually do the function calculation.
  71. PROC Graph_Pass:(f$)
  72.     EXTERNAL WinH%, WinW%, RMin, RMax, Mesh&, DrawWindow%
  73.     EXTERNAL Zoom, XCent%, YCent%, Offscreen%, Uselines%
  74.     GLOBAL x // EVAL's cannot reference locals
  75.     LOCAL y, max%, isMove%, Step, Scale
  76.  
  77.     Step = RMax/Mesh&
  78.     IF Zoom > 0
  79.         Scale = (WinW%/(RMax-RMin)) * Zoom
  80.     ELSE
  81.         Scale = (WinW%/(RMax-RMin)) / (-Zoom)
  82.     ENDIF
  83.     
  84.     isMove%=KTrue%
  85.     x=RMin
  86.     BUSY "Plotting..."
  87.     ONERR ErrHandler
  88.     gUSE DrawWindow%
  89.  
  90.     // Vary X from RMin to RMax in steps of (1/mesh)
  91.     // and calculate the function from each point
  92.     WHILE x <= RMax
  93.         y=(EVAL(f$))*Scale
  94.         IF (yCent%-y > (WinH%*2)) AND (NOT Offscreen%)
  95.             isMove%=KTrue%
  96.         ENDIF
  97.         IF isMove%
  98.             gAT (x*Scale)+xCent%, yCent%-y
  99.             isMove%=KFalse%
  100.         ELSEIF UseLines%
  101.             GLINETO (x*Scale)+xCent%, yCent%-y
  102.         ELSE
  103.             gAT (x*Scale)+xCent%, yCent%-y
  104.             gLINEBY 0, 0
  105.         ENDIF
  106.         x+=Step
  107.         CONTINUE // skip the error handler if there
  108.                  // was no error!
  109. ErrHandler::
  110.         // This is somewhat odd. We skip some errors, and
  111.         // handle others sensibly:
  112.         IF ERR = KErrDivideByZero%
  113.             isMove% = KTrue% // Try and draw a hole in the graph
  114.         ELSEIF (ERR = KErrUnderflow%) OR (ERR = KErrOverflow%) OR (ERR = KErrInvalidArgs%)
  115.             isMove% = KTrue% // These are real errors, but we try and proceed anyway
  116.         ELSE
  117.             // Real errors that we report.
  118.             ALERT(ERR$(ERR),"("+GEN$(ERR,3)+")")
  119.             BUSY OFF : ONERR OFF : RETURN
  120.         ENDIF
  121.         x+=Step // We missed this when we entered the handler
  122.     ENDWH
  123.     BUSY OFF
  124.     ONERR OFF
  125. ENDP
  126.  
  127. // Draw the axis
  128. PROC Axis:
  129.     EXTERNAL WinH%, WinW%, RMin, RMax
  130.     EXTERNAL Zoom, yCent%, xCent%, DrawWindow%
  131.     LOCAL x, y, i%, max%, Scale
  132.     
  133.     IF Zoom > 0
  134.         Scale = (WinW%/(RMax-RMin)) * Zoom
  135.     ELSE
  136.         Scale = (WinW%/(RMax-RMin)) / (-Zoom)
  137.     ENDIF
  138.  
  139.     gUSE DrawWindow%
  140.     
  141.     gAT (RMin*Scale)+XCent%, yCent%
  142.     gLINETO (RMax*Scale)+XCent%, yCent%
  143.  
  144.     // Domain max size now known.
  145.     gAT xCent%, 0
  146.     gLINETO xCent%, WinH%
  147.  
  148.     max% = Mod&:(WinW%,Scale)
  149.     i%=RMin
  150.     gFONT KFontArialNormal8&
  151.     DO
  152.         gAT i%*Scale+XCent%, yCent%
  153.         gLineBy 0,5
  154.         IF i% <> 0
  155.             gAT i%*Scale+XCent%-5, yCent%+12
  156.             gPRINT i%
  157.         ENDIF
  158.         gAT XCent%,yCent%-(Scale*i%)
  159.         gLineBy 5,0
  160.             IF i% <> 0
  161.             gAT XCent%+5,yCent%-(Scale*i%)
  162.             gPRINT i%
  163.         ENDIF
  164.         i%++
  165.     UNTIL i% > RMax
  166. ENDP
  167.  
  168. // Draw a caption for the graph. Overprint "<" and "_" to
  169. // get inequalities.
  170. PROC Caption:
  171.     EXTERNAL WinH%, f$, RMin, RMax, overPrintCount%
  172.     LOCAL ypos%
  173.     gFONT KFontArialNormal11&
  174.     ypos% = WinH% - 6 - (overPrintCount%*11)
  175.  
  176.     gAT 5,ypos%
  177.     gPRINT f$+"    "+GEN$(RMin,3)+" <"
  178.     gMOVE -gTWIDTH("<"),0
  179.     gPRINT "_ x <"
  180.     gMOVE -gTWIDTH("<"),0
  181.     gPRINT "_ "+GEN$(RMax,3)
  182. ENDP