Алгоритм 2D ссылочного перевода

Я пытаюсь построить график функций,

Пользователь вводит функцию xmin, xmax, ymin, ymax. Я получил x, y для всех точек.

Теперь я хочу перевести эту исходную ссылку на Canvas, начиная с 0,0 до 250,250.

Есть короткий путь или мне просто проверить

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

и т.д ..

Также этот базовый подход не оптимизирует выборку. Например, если моя функция f (x) = 5, мне не нужно выбирать xrange в 500 точках, мне нужно только две точки. Я мог бы провести несколько эвристических проверок.

Но для такой функции, как sin (2 / x), мне нужно больше выборки вокруг x (-1,1), как вы подойдете к такой вещи?

Спасибо


person coulix    schedule 05.12.2008    source источник


Ответы (3)


Вместо того, чтобы перебирать x в исходных координатах, перебрать холст и затем преобразовать обратно к исходным координатам:

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)
}

Это дает вам ровно одну оценку функции для каждого столбца холста.

person David Norman    schedule 05.12.2008
comment
А как насчет части отбора проб? - person Shashwat; 17.07.2012
comment
Это делает ровно одну выборку на пиксель, чего должно хватить для большинства функций. Вы можете динамически проверять соседние пиксели в соседних столбцах холста, чтобы увидеть, далеко ли они друг от друга, и при желании добавить больше образцов. - person David Norman; 17.07.2012

  1. Вы можете оценить производную (если она у вас есть).
  2. Вы можете использовать двунаправленный (дихотомический) подход: оценить разницу и при необходимости разделить сегмент.
person avp    schedule 05.12.2008

Думаю, я бы начал с рассуждений об этом с точки зрения преобразований контекстов холста в математические.

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

maths_x -> maths_y

Вы перебираете точки отображаемого объекта, перебирая в цикле canvas_x.

Это привело бы к некоторым простым функциям:

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)

Как только вы здесь окажетесь, записать эти простые функции в код будет относительно просто.

Оптимизируйте отсюда.

Я думаю, что для этого подхода вам не нужно слишком много знать о частотах дискретизации, потому что вы выбираете с частотой, подходящей для дисплея. Это было бы не оптимально - ваш пример y = 5 - хороший пример, но вы гарантированно не выберете больше, чем можете отобразить.

person jamesh    schedule 05.12.2008