# simplegraph4.frink

``` // 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 version of the program can also graph INEQUALITIES, which have // less-than or greater-than symbols instead of just equals. // // For example, try // // abs[y^2 + x^4 - 1] < cos[x] //  // This uses a recursive method to subdivide and test rectangles. lasteq = "" // If there are arguments to the program, graph them, otherwise prompt. while func = (length[ARGS] > 0 ? ARGS@0 : input["Enter equation: ", lasteq]) {    hasInequality = false    certEq = undef    lasteq = certFunc = func    // If there's an inequality, let's make a test equation to see if we can    // plot an entire rectangle using the "CERTAINLY" comparators.    if func =~ %r/([<>]|!=)/    {       hasInequality = true       certFunc =~ %s/<=/ CLE /g  // Replace <= with certainly less than or equals       certFunc =~ %s/>=/ CGE /g  // Replace >= with certainly greater than or equals       certFunc =~ %s/</ CLT /g   // Replace <  with certainly less than       certFunc =~ %s/>/ CGT /g   // Replace >  with certainly greater than       certFunc =~ %s/!=/ CNE /g   // Replace = with certainly not equals       certFunc =~ %s/=/ CEQ /g   // Replace = with certainly equals       certEq = parseToExpression[certFunc]    }    // These replacements turn normal comparator and equality tests into    // "POSSIBLY EQUALS" tests.    func =~ %s/<=/ PLE /g  // Replace <= with possibly less than or equals    func =~ %s/>=/ PGE /g  // Replace >= with possibly greater than or equals    func =~ %s/</ PLT /g   // Replace <  with possibly less than    func =~ %s/>/ PGT /g   // Replace >  with possibly greater than    func =~ %s/!=/ PNE /g   // Replace = with possibly not equals    func =~ %s/=/ PEQ /g   // Replace = with possibly equals    eq = parseToExpression[func]    println[func]    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, certEq, 10]    g.show[]    g.write["graph2.png",1024,1024]    if length[ARGS] > 0       exit[] } // 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, certEq, 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)       {          if (certEq != undef)  // Do we have inequalities and a CERTAINLY test?             if eval[certEq] == true             {                // If the entire rectangle is a solution, then fill the                // rectangle and stop further recursion on this rectangle.                g.fillRectSides[x1, -y1, x2, -y2]                return             }          // Further subdivide the rectangle into 4 quadrants and recursively          // test them all          cx = (x1 + x2)/2          cy = (y1 + y2)/2          testRect[x1, cx, y1, cy, g, eq, certEq, nextLevel]          testRect[cx, x2, y1, cy, g, eq, certEq, nextLevel]          testRect[x1, cx, cy, y2, g, eq, certEq, nextLevel]          testRect[cx, x2, cy, y2, g, eq, certEq, nextLevel]       } else            if (res)             // Valid point               g.fillRectSides[x1, -y1, x2, -y2]            else            {               // Error in evaluating point, plot in red.               g.color[1,0,0]               g.fillRectSides[x1, -y1, x2, -y2]               g.color[0,0,0]            }    } } ```