views:

122

answers:

3

Hi,

I am trying to build a function grapher,

The user enters xmin, xmax, ymin, ymax, function. I got the x, y for all points.

Now i want to translate this initial referential to a Canvas starting at 0,0 up to 250,250.

Is there a short way or should i just check

if x < 0 
new x = (x - xmin) * (250 / (xmax - xmin)) ?

etc ..

Also this basic approach does not optimise sampling. For example if my function f(x) = 5 i dont need to sample the xrange in 500 points, i only need two points. I could do some heuristic checks.

But for a function like sin(2/x) i need more sampling around x (-1,1) how would you aproach such a thing ?

Thanks

A: 
  1. You can estimate the derivative (if you have one).
  2. You can use bidirectional (dichotomic) approach: estimate the difference and split the segment if necessary.
avp
A: 

I think I would start by reasoning about this in terms of transformations from canvas to maths contexts.

(canvas_x, canvas_y) -> (maths_x, maths_y)
(maths_x, maths_y)   -> (canvas_x, canvas_y)

maths_x -> maths_y

You iterate over the points that a displayable, looping over canvas_x.

This would translate to some simple functions:

maths_x = maths_x_from_canvas_x(canvas_x, min_maths_x, max_maths_x)
maths_y = maths_y_from_maths_x(maths_x) # this is the function to be plotted.
canvas_y = canvas_y_from_maths_y(maths_y, min_maths_y, max_maths_y)

if (canvas_y not out of bounds) plot(canvas_x, canvas_y)

Once you get here, it's relatively simple to write these simple functions into code.

Optimize from here.

I think that for this approach, you won't need to know too much about sample frequencies, because you sample at a rate appropriate for the display. It wouldn't be optimal - your example of y = 5 is a good example, but you'd be guaranteed not to sample more than you can display.

jamesh
+1  A: 

Instead of iterating over x in the original coordinates, iterate over the canvas and then transform back to the original coordinates:

for (int xcanvas = 0; xcanvas <= 250; i++) {
    double x = ((xmax - xmin) * xcanvas / 250.0) + xmin;
    double y = f(x);

    int ycanvas = 250 * (y - ymin) / (ymax - ymin) + .5;

    // Plot (xcanvas, ycanvas)
}

This gives you exactly one function evaluation for each column of the canvas.

David Norman