simplegraph3.frink

View or download simplegraph3.frink in plain text format


// This is a simple but rather interesting program that graphs equations.
// You enter equations in terms of x and y, something like one of the
// following:
//
//  y = sin[x]
//
//  x^2 + y^2 = 81
//
//  y cos[x] = x sin[y]
// 
// This uses a recursive method to subdivide and test rectangles.

use ArbitraryPrecision.frink

lasteq = ""

while func = input["Enter equation: ", lasteq]
{
   lasteq = func
   func =~ %s/>=/ PGE /g    // Replace >= with possibly greater than or equals
   func =~ %s/<=/ PLE /g    // Replace <= with possibly less than or equals
   func =~ %s/!=/ PNE /g    // Replace != with possibly not equals
   func =~ %s/>/ PGT /g     // Replace > with possibly greater than
   func =~ %s/</ PLT /g     // Replace < with possibly less than
   func =~ %s/=/ PEQ /g     // Replace = with possibly equals
   eq = parseToExpression[func]
   println[inputForm[eq]]

   g = new graphics

   // Change the last number to vary the resolution.  This is the number
   // of doublings, so if the number is 10 we have 2^10=1024 doublings for
   // a resolution of 1024x1024.
   testRect[-10,10,-10,10, g, eq, 10]
   g.show[]
   g.write["graph2.png",1024,768]
}

// Recursive function to test an interval containing the specified bounds.
// If no possible solution exists, the recursion halts.  If a possible solution
// exists, this breaks it down into 4 sub-rectangles and tests each of them
// recursively.  level is the maximum number of levels to split, so the total
// resolution of the final graph will be 2^level.
testRect[x1, x2, y1, y2, g, eq, level] :=
{
   nextLevel = level - 1

   x = new interval[x1, x2]
   y = new interval[y1, y2]
   
   // Test the rectangle.  If it possibly contains solutions, recursively
   // subdivide.
   res = eval[eq]
   
   if res or res==undef
   {
      if (nextLevel >= 0)
      {
         cx = (x1 + x2)/2
         cy = (y1 + y2)/2
         testRect[x1, cx, y1, cy, g, eq, nextLevel]
         testRect[cx, x2, y1, cy, g, eq, nextLevel]
         testRect[x1, cx, cy, y2, g, eq, nextLevel]
         testRect[cx, x2, cy, y2, g, eq, nextLevel]
      } else
           if (res)             // Valid point
              g.fillRectSides[x1, -y1, x2, -y2]
           else
           {
              // Error in evaluating point
              g.color[1,0,0]
              g.fillRectSides[x1, -y1, x2, -y2]
              g.color[0,0,0]
           }
   }
}


View or download simplegraph3.frink in plain text format


This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 17478 days, 1 hours, 28 minutes ago.