2011-01-15 21 views
5

Así que estoy escribiendo una calculadora gráfica. Hasta ahora tengo un grapher semi funcional, sin embargo, estoy teniendo dificultades para lograr un buen equilibrio entre gráficos precisos y curvas de aspecto suave.Cómo implementar un grapher en C#

La implementación actual (semi-pseudo-código) se ve algo como esto:

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

El problema con esto es ya que sólo añade un punto a cada valor entero, gráficos terminan distorsionada cuando sus puntos de inflexión no caiga en enteros (por ejemplo, sin (x)^2).

alt text

he intentado incrementar i por algo más pequeño (como 0.1), que funciona, pero el gráfico se ve muy áspera.

alt text

estoy usando C# y GDI +. Tengo SmoothingMethod configurado en AntiAlias, por lo que ese no es el problema, como se puede ver en el primer gráfico. ¿Hay algún problema con dibujar curvas con muchos puntos? ¿Los puntos quizás deberían estar ubicados exactamente en píxeles?

Estoy seguro de que algunos de ustedes han trabajado en algo muy similar antes, así que ¿alguna sugerencia? Mientras lo hace, ¿tiene alguna sugerencia para graficar funciones con asíntotas? p.ej. 1/x^2

P.S. No estoy buscando una biblioteca que haga todo esto, quiero escribirla yo mismo.

+0

¿Qué quiere decir con "el gráfico se ve muy duro"? aumentar el número de puntos es el camino a seguir, para que se vea más suave. Y hacer que los X-steps sean más pequeños (1 -> 0.1) * no * los aumenta. – user492238

+0

Además, no sé a qué se refiere con "sugerencias para funciones gráficas con asíntotas". ¿Que esperas? ¿Cómo se manejan de manera diferente a otros gráficos? Ellos no son. – user492238

+0

He editado para que quede más claro. – ian93

Respuesta

1

Bien, solucioné el problema. En algún lugar del proceso de dibujo, estaba usando int en lugar de float.

2

Al renderizar un gráfico, siempre está cometiendo errores de redondeo porque un mapa de bits es discreto y el gráfico no lo es.

Hay varias formas de afrontamiento:

  1. el uso de anti-aliasing; solo hace que el gráfico se vea más suave.
  2. utilizan una interpolación sin lineair. Dibujar desde el punto a hasta el b usando una interpolación linealir causa ángulos. Calcular la pendiente de la gráfica (no del segmento de línea!) En cada punto y alimentar a la pendiente para el método de interpolación (bicúbico o Bezier curva)

Utilización de las API de vectores tales como WPF o Silverlight podría facilitar las cosas a implementar.

Cuidar las asíntotas es bastante difícil. Primero debe encontrarlos y luego omitir el valor para poder hacer el 'hoyo' en el gráfico.

Cuestiones relacionadas