Patrick Mineault has posted an elegant solution (he says so himself, and I agree) for graphing a function in Flash using the curveTo method. He used it on the Gaussian curve and it’s efficient and it looks great. He shows a few other examples as well. The method, wrapped in an ActionScript class, adaptively adjusts the number of curves to better approximate the function.
I tried it on an ellipse and found two difficulties: I needed to guard against plotting NaNs, which drew lines heading off the screen, and I wanted the whole ellipse, not just the top or bottom half. I added some code to Patrick’s class for the NaN conditions, and to get the whole ellipse, I plotted two functions, one for the top and one for the bottom. But I could never get the two halves to quite close the gaps at their ends; they were still just barely visible with 4571 curves. So I’ve implemented a parametric version PGraph.as so I can represent the ellipse as x(theta) and y(theta), and voilà. (Or “whalla” as they say in the sticks.)
But then I ran it on some other conic sections, and found that I was drawing lines connecting the legs of the hyperbola — ugly! So I’ve also added the ability for the user to specify the discontinuities, as x values for the regular version, and as parameter values for the parameterized version. It would be nice to have the class find the discontinuities automatically, but I think that would be hard.
One thing that’s puzzling me is the results for sin(1/x). This function should never exceed (-1, +1) in the y direction, and yet the plot goes way outside that range.
You can download the modified Graph class, the PGraph class, and a DrawGraph test class with examples here.



Using it to draw parametric functions was actually going to be my next blog post, but looks like you beat me to it :) Nice stuff. Some functions which have very pathological behaviour are bound to be difficult to draw properly, like sin(1/x). In that case, because of the rapid succession of cycles near 0, at some point the graphing function will sample two points where one has a large positive derivative and another point with a large negative derivative and while the intersection is between the two points, it’s way, way off. I think one reasonable way to solve this is adding a check if the derivatives are too different between two very close points, and if so, revert to a line drawing mode. That wasn’t really my point however, since it was more for drawing ‘nice’ functions so they render well without having a bunch of lines on screen. Note that the algo can be retrofitted to AS1 and ECMAScript to be used as a JSFL tool (like Keith Peter’s sinewave tool)
Comment by Patrick Mineault — November 2, 2005 @ 6:22 pm