vd.frink

View or download vd.frink in plain text format


// This demonstrates animating a two-dimensional graph using interval
// arithmetic techniques.  These techniques are deep and subtle and amazingly
// powerful.  They allow you to easily graph arbitrary equations that would be
// very tricky otherwise.
//
// See:  http://futureboy.us/frinkdocs/#IntervalArithmetic
//
// For other examples of very simple interval graphing, see:
// 
// http://futureboy.us/fsp/colorize.fsp?f=simplegraph.frink
// http://futureboy.us/fsp/colorize.fsp?f=simplegraph3.frink
//
//  Interactive web-based grapher:
// http://futureboy.us/fsp/simplegraph.fsp

g = new graphics
win = g.show[]

showApproximations[false]

a = new Animation[10/s]

for z = .2 to 0 step -.01
{   
   eqStr = "(x^2 + y^2 - 1)^3 - x^2 y^3 = " + format[z,1,3]
   eqStr2 = eqStr

   // There's a lot of magic in the "Possibly-Equals" (PEQ) operator!
   eqStr2 =~ %s/=/PEQ/g
   eq = parseToExpression[eqStr2]

   g = new graphics
   g.color[1,0,0]

   // 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[-3/2,3/2,-3/2,3/2, g, eq, 7]

   g.font["Serif","italic",.1]
   g.color[0,0,0]
   g.text[eqStr,0,-1/4]

   if (z == 0)
   {
      g.font["SansSerif", "bold", .15]
      g.text["Frink loves you.", 0, 0]
   }

   a.add[g]
   win.replaceGraphics[g]
}

a.write["vd.gif",400,400]

// 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 vd.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 17645 days, 8 hours, 29 minutes ago.