1

I am working on a graphing calculator application, and of course, the main feature of the application is to display graphs.

Right now, this is how my algorithm of plotting graphs works: I divide the drawing canvas in N intervals (where N is defined the application's settings, default value is about 700). For each interval, I evaluate the function for the two ends, and I draw a segment between the two points.

Here are the disadvantages I found to this method:

  • The precision of the graph isn't great (for example the function sin(tan(x)) )
  • Rendering gets slow for a higher number of intervals (e.g. N is above 1000). Also, zoom and navigation controls suffer.

So is there a better approach to drawing graphs?

I am programming in C# (WPF), but I think this is irrelevant, because I am looking for an algorithm.

Tibi
  • 4,015
  • 8
  • 40
  • 64
  • What's the slow part? The calculation or putting a pixel on the screen? Putting pixels on the screen can be incredibly slow, if that is the problem look up C#'s fastbitmap. – Carra Apr 10 '12 at 15:43

4 Answers4

1

You don't need to write your own algorithm if you are plotting some arbitrary functions. Use a graph control from a relevant library, see here and provide the neccessary data (x, y cordinates).

Community
  • 1
  • 1
ldgorman
  • 1,553
  • 1
  • 14
  • 39
  • 1
    Where's the fun in writing code if I use libraries for every single thing I do? – Tibi Apr 10 '12 at 15:17
  • 1
    The fun comes from the maths not the coding and besides, you will enjoy doing much more powerful things than writing graph plotting routines if you don't waste your time on things like this. – ldgorman Apr 10 '12 at 15:19
  • This is a research project, not a commercial application, so I want to improve my programming skills. And I doubt libraries will give me as much control over how the finished result looks like. – Tibi Apr 10 '12 at 15:22
  • if you are interested in seeing some source code for plotting etc see [here](http://www.codeproject.com/Articles/1546/Plot-Graphic-Library) – ldgorman Apr 10 '12 at 15:23
  • or a c# one [here](http://www.codeproject.com/Articles/32836/A-simple-C-library-for-graph-plotting) – ldgorman Apr 10 '12 at 15:24
1

I hope i can help you with this snippet of C++ program which i made few years back using primitive graphics.h ported for mingw compiler. The variable names are pretty much clear.

void func_gen(char expr[100],float precision,int color)
{
     float x=-(xres/2)/(float)zoom_factor;
     float max_range=-x;
     while(x<=max_range)
     {
        float y;
        y = evalu(expr,x);          //user defined function which i used to evaluate ann expression
        float xcord=xby2+zoom_factor*x+xshift;
        float ycord=yby2-zoom_factor*y+yshift;
        if(xcord<=xres && xcord>=0 && ycord>=0 && ycord<=yres)
            putpixel(xcord,ycord,color);
            x=x+precision;
     }
}

This method gets pretty slow when i reduce the precision value (which actually increases the precision of the plot :p, sorry for noobness)

nims
  • 3,751
  • 1
  • 23
  • 27
  • Okay, so you are drawing it pixel by pixel. I understand, it's a similar idea to mine. The problem is that C# is a high level language, and drawing pixel by pixel is extremely slow, this is why I draw segments instead of pixels. – Tibi Apr 10 '12 at 15:26
1

A better approach would be to use adaptive interval sizes. That is, start with relatively coarse intervals, say 20. For each interval, compute the function for the interval ends and the middle. If the middle point is close to the line connecting the two end points, draw a line and you're done with that interval. If not, split the interval in two and repeat with the two smaller intervals.

If the interval gets too small without converging to a line, you've probably found a discontinuity and should not connect the interval endpoints.

xan
  • 7,511
  • 2
  • 32
  • 45
  • Yes, this is an great idea. Though, I'm afraid of cases like the sine function where the shape of the function may trick the algorithm: the points where I calculate the function may have a very close value, but between the values would be totally different. – Tibi Apr 11 '12 at 18:17
  • Good point, though any sampling algorithm, including your original, is liable to fall for that. – xan Apr 12 '12 at 02:22
0

I think you should do with DrawPath. That method use an auxiliary structure (a GraphicsPath) optimized just for kind of task as you are coding. edit A small optimization could be to eval the function just at the left point of the segment, and eval at close point just on last segment.

CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • These are part of Forms, not WPF. The question was about the best algorithm, not the functions used. – Tibi Apr 10 '12 at 15:42
  • WPF has a [Path shape](http://msdn.microsoft.com/en-us/library/system.windows.shapes.path.aspx). Should work as the Forms counterpart, I think – CapelliC Apr 10 '12 at 15:54