2012-04-10 2 views
1

Я работаю над графическим калькулятором, и, конечно же, основной особенностью приложения является отображение графиков.Каков наилучший подход к построению графиков?

Прямо сейчас, так работает мой алгоритм построения графиков: я разделяю холст чертежа в интервале N (где N определяется настройками приложения, значение по умолчанию - около 700). Для каждого интервала я оцениваю функцию для двух концов, и я рисую сегмент между двумя точками.

Вот недостатки, которые я нашел этому методу:

  • Точность графики не велика (например, функция sin(tan(x)))
  • рендеринга медленно для большего числа интервалов (например, N превышает 1000). Кроме того, пострадали средства масштабирования и навигации.

Итак, есть ли лучший подход к рисованию графиков?

Я программирую на C# (WPF), но я думаю, что это не имеет значения, потому что я ищу алгоритм.

+0

Что такое медленная часть? Вычисление или установка пикселя на экран? Помещение пикселов на экран может быть невероятно медленным, если это проблема, посмотрите на скоростную карту C#. – Carra

ответ

1

Лучшим подходом было бы использовать адаптивный интервалы размеров. То есть, начните с относительно грубых интервалов, скажем 20. Для каждого интервала вычислите функцию для концов интервала и середины. Если средняя точка близка к линии, соединяющей две конечные точки, нарисуйте линию, и вы закончите с этим интервалом. Если нет, разделите интервал на два и повторите с двумя меньшими интервалами.

Если интервал становится слишком маленьким, не сходясь к линии, вы, вероятно, обнаружили разрыв и не должны связывать конечные точки интервала.

+0

Да, это отличная идея. Хотя, я боюсь таких случаев, как функция синуса, где форма функции может обмануть алгоритм: точки, в которых я вычисляю функцию, могут иметь очень близкое значение, но между значениями будут совершенно разные. – Tibi

+0

Хорошая точка, хотя любой алгоритм выборки, включая ваш оригинал, может упасть для этого. – xan

1

Вам не нужно писать собственный алгоритм, если вы производите произвольные функции. Используйте управление графом из соответствующей библиотеки, см. here и укажите необходимые данные (x, y cordinates).

+1

Где интересно писать код, если я использую библиотеки для каждой вещи, которую я делаю? – Tibi

+1

Веселье исходит из математики, а не для кодирования, и, кроме того, вам понравится делать гораздо более мощные вещи, чем писать графические схемы, если вы не тратите время на такие вещи. – ldgorman

+0

Это исследовательский проект, а не коммерческое приложение, поэтому я хочу улучшить свои навыки программирования. И я сомневаюсь, что библиотеки дадут мне такой же контроль над тем, как выглядит законченный результат. – Tibi

1

Надеюсь, я могу помочь вам с этим фрагментом программы на C++, который я сделал несколько лет назад, используя примитивную графику.h, перенесенную для компилятора mingw. Имена переменных довольно понятны.

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

Этот метод становится довольно медленно, когда я уменьшить значение точности (которая на самом деле повышает точность участка: р, извините за noobness)

+0

Итак, вы рисуете пиксель за пикселем. Я понимаю, это моя идея. Проблема в том, что C# является языком высокого уровня, а рисование пикселя за пикселем происходит крайне медленно, поэтому я рисую сегменты вместо пикселей. – Tibi

0

Я думаю, что вы должны делать с DrawPath. Этот метод использует вспомогательную структуру (a GraphicsPath), оптимизированную только для какой-либо задачи, поскольку вы кодируете. Редактировать Небольшая оптимизация может состоять в том, чтобы оценить функцию только в левой части сегмента, а eval - в близкой точке только на последнем сегменте.

+0

Это часть Форм, а не WPF. Вопрос касался лучшего алгоритма, а не используемых функций. – Tibi

+0

WPF имеет [Форма пути] (http://msdn.microsoft.com/en-us/library/system.windows.shapes.path.aspx). Должен работать как копия форм, я думаю – CapelliC