2011-01-15 2 views
5

Итак, я пишу графический калькулятор. Пока у меня есть полуфункциональный граф, однако мне трудно найти хороший баланс между точными графиками и гладкими кривыми.Как реализовать grapher в C#

Текущая реализация (пол-псевдо-код) выглядит примерно так:

for (float i = GraphXMin; i <= GraphXMax; i++) 
{ 
    PointF P = new PointF(i, EvaluateFunction(Function, i) 
    ListOfPoints.Add(P) 
} 
Graphics.DrawCurve(ListOfPoints) 

Проблема с этим, так как это только добавляет точку на каждом целом значении, графики в конечном итоге искаженные, когда их точка поворота не попадают на целые числа (например, sin (x)^2).

alt text

Я попытался приращением я чем-то меньшим (как 0,1), который работает, но график выглядит очень грубо.

alt text

Я использую C# и GDI +. У меня есть SmoothingMethod для AntiAlias, так что это не проблема, как вы можете видеть из первого графика. Есть ли какая-то проблема с рисованием кривых с большим количеством точек? Должны ли точки, возможно, располагаться точно на пикселях?

Я уверен, что некоторые из вас уже работали над чем-то очень похожим, поэтому любые предложения? Пока вы на нем, есть ли у вас какие-либо предложения по графическим функциям с асимптотами? например 1/x^2

P.S. Я не ищу библиотеку, которая делает все это - я хочу написать ее сам.

+0

Что вы подразумеваете под термином «график выглядит очень грубым»? увеличение количества очков - это путь, чтобы сделать его более гладким. И уменьшение X-шагов (1 -> 0,1) * * увеличивает их. – user492238

+0

Также я не знаю, что вы подразумеваете под «предложениями для графического отображения функций с асимптотами». Что вы ожидаете? Как они обрабатываются по-разному с другими графиками? Они не. – user492238

+0

Я отредактировал, чтобы сделать его более ясным. – ian93

ответ

1

ОК, я исправил проблему. Где-то в процессе рисования я использовал int, а не float.

2

При рендеринге графика вы всегда делаете ошибки округления, потому что битмап дискретный, а график нет.

Там несколько способов совладания:

  1. использование антиалиасинга; это просто делает график более гладким.
  2. использовать интерлайн-линию без линии. Рисование из точки a в b с использованием интерполяции линии приводит к углам. Вычислить наклон графика (не отрезка!) В каждой точке и кормить наклон к методу интерполяции (бикубическая или кривая Безье)

Использование векторных API-интерфейсов, таких как WPF или Silverlight может сделать вещи проще воплощать в жизнь.

Уход за асимптотами довольно сложно. Сначала вы должны найти их, а затем пропустить значение, чтобы вы могли сделать «отверстие» на графике.

Смежные вопросы