## 176 Equation Graphing

### Description

*This week’s quiz idea provided and written by Martin DeMello.*

Back when the world was shiny and new, and BBC Basic my language of choice and necessity, one of the fun little programs I wrote was a simple equation grapher. Two things that made it simple were (i) the ever-useful EVAL function, and (ii) the almost trivial ability to pick a colour and a pair of coordinates and put a friendly glowing pixel onto the screen. Instant gratification writ large. Well, anything that Basic can do, Ruby should be able to, so your task this week is to whip out your favourite graphics toolkit or library and write a program that

- Asks for a function of one variable, x
- Asks for the region of the graph to display (xmin, xmax, ymin, ymax)
- Plots the graph

You can trust the user to input a syntactically correct function, but don’t forget that it might behave badly for certain values of x (e.g. 1/x where x=0). Style points for making the main loop look trivial :)

Here’s a neat little online grapher you can use to visually check your output.

### Summary

I have to say, I think Martin provided a great quiz here… His description was old-school, and most of the solutions have that feeling. In return, I’m looked at the solutions from a similar viewport. While the solution from *Jesse Brown* is simple and makes use of `gnuplot`

– and would generally be a good way to solve the problem – it ain’t old-school. (Of course, this means that if you have a real graphing problem, using `gnuplot`

*would* be a good idea.)

*Michael Suchanek* provided a solution using RubyX11. Oh man, does that bring back memories… Michael just opened up a can of X11 goodness that, with Ruby, looks trivial compared to my old X11 C code. I am rather tempted to study this library and start playing, but I do have papers to write and books to analyze. Please take a look at Michael’s code, because X11 is definitely old-school, definitely powerful, and RubyX11 makes it definitely cool.

The ASCII solution from *brabuhr* is also several flavors of awesome. Heck, if we geeks can still be entertained playing ASCII games like Nethack and Dwarf Fortress, then why not our function plotters? This solution is also totally Ruby, with a single, trivial function that accepts your “equation” as a block… Top notch, dear sir.

I am going to go into a bit of detail with *Martin DeMello*’s solution, not because he wrote the quiz, but it reminded me most of my *oldest* coding experience: BASIC. Sure, there’s a class and a function or two in there, but I could imagine line numbers in front of the code and almost expected to see a `GOTO`

statement in there somewhere.

Plus, it makes use of the cool, little, cross-platform Ruby library for making little applications: Shoes. While Shoes still seems a little rough around the edges, it’s a fun environment and API, a kind of toy that recalls days on the Commodore 64. (I use Apple computers nowadays, but back then, Commondore was king!)

Here’s the main body:

```
Shoes.app :height => Y, :width => X do
g = Grapher.new
background rgb(255, 255, 255)
fill white
stroke black
strokewidth 1
u, v = nil
Xmin.step(Xmax, (Xmax - Xmin)/(X*1.0)) {|i|
begin
x0, y0 = g.at(u,v)
u, v = i, g.fn(i)
x, y = g.at(u,v)
if g.bounded?(x,y) and g.bounded?(x0,y0)
line(x0, y0, x, y)
end
rescue
end
}
end
```

There are three essential things going on here. First, the creation of a Shoes application and the calls to prepare it, such as `fill white`

and `strokewidth 1`

. Second is the creation of a `Grapher`

object and the calls into it: we’ll come back to that. Finally, the main loop is here, contained in this one line:

` Xmin.step(Xmax, (Xmax - Xmin)/(X*1.0)) {|i|`

`Numeric#step`

is a method that works for either integers or floats, and counts from the first number (`Xmin`

) up to the second number (`Xmax`

) by the provided increment. Martin divides the window width into the user-specified domain. This increment will ensure the evaluations contained within the loop are evaluated once per horizontal pixel.

The multiplication by 1.0 serves to convert X (and the rest of that expression) to floating-point. Now, typically this might be done with the `to_f`

method. But multiplying by 1.0 seems old-school, especially as it is one character less that `.to_f`

. Rad.

The `Grapher`

is a simple class containing three methods. `bounded?`

and `fn`

are fairly straightforward; the former checks that a coordinate pair is contained within the window’s drawing area, while the latter evaluates the function provided by the user. Then there’s `Grapher#at`

:

```
def at(x,y)
[((x - Xmin) * XScale).to_i, Y - ((y - Ymin) * YScale).to_i] rescue nil
end
```

This function converts the pair `(x, y)`

from function-space values to window-space values. That is, it maps the evaluation of the function to the appropriate coordinate within the Shoes window. There is some repetition here that could stand to be refactored into a general `lerp`

method (i.e. linear interpolation), but as we’re in old-school mode, I’ll let it slide.

So, back in the main loop, we can now read this easily. For each iteration, we evaluate the provided function at each pixel column of the domain (`i`

, stored to `u`

) to get the pixel row (`v`

) via method `fn`

. The `(u, v)`

pair is converted to window coordinates `(x, y)`

via method `at`

. The previous window coordinate is recalculated into `(x0, y0)`

, and the Shoes’ `line`

method is called to draw a line between the two window coordinates.

Good show, gents. Now, if I can get Ruby running on this ol’ Commodore 64 sitting in the closet, my life will be complete.