Download or view simplegraph4.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 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]
}
}
}
Download or view simplegraph4.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, eliasen@mindspring.com