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:  https://frinklang.org/#IntervalArithmetic
//
// For other examples of very simple interval graphing, see:
// 
// https://frinklang.org/fsp/colorize.fsp?f=simplegraph.frink
// https://frinklang.org/fsp/colorize.fsp?f=simplegraph3.frink
//
//  Interactive web-based grapher:
// https://frinklang.org/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 18014 days, 12 hours, 30 minutes ago.