Como funciona GDF

Mi programa no utiliza bibliotecas ni codigo de otros autores y esta totalmente desarrollado en Basic. Sin embargo, como habrán podido comprobar, la velocidad de ejecución es similar a la muchos graficadores de C y Java. Frecuentemente me comentan que es bastante rapido para estar en Basic. La verdad es que el motor de evaluación (la parte de código que calcula el valor de una ecuación para unos valores concretos de las variables) es mas lento que uno hecho en C o Java, pero la velocidad al graficar es muy buena, porque esta especialmente desarrollado para ese trabajo. Esto lo he logrado desarrollando una cache de terminos en el arbol de evaluación, de manera que al graficar una función, que es lo que le interesa al usuario, la velocidad es similar a la de los graficadores que trabajan con lenguajes mas rápidos que el Basic.
Ahora les explicacaré en detalle como funciona. Para evaluar una función se hace un arbol en memoria con los terminos de la misma y se resuleve en forma recursiva.

Por ejemplo, para evaluar: 1 + ( 2 * 2 ) - 3, el programa lo interpreta de la siguiente forma.

Arbol de evaluación

Internamente se busca el primer operador desde la derecha y se hacen los siguientes "razonamientos"
1 + ( 2 * 2 ) - 3 "1 + ( 2 * 2 )" desconocido operado con 3 => Resolver  "1 + ( 2 * 2 )" y operar luego
1 + ( 2 * 2 ) 1 operado con desconocido "( 2 * 2 )" => Resolver "(2 * 2)" y operar luego
2 * 2 2 operado con 2 => Resolver = 4
1 + 4 1 operado con 4 => Resolver = 5 (aqui se ejecuta el "operar luego" que esta en la segunda linea)
5 - 3 5 operado con 3 => Resolver = 2 (ahora el "operar luego" de la primera linea de la tabla)

En definitva, lo unico que el programa sabe hacer son operaciones basicas, como 2+2, 4*3, etc... Estas operaciones se buscan de derecha a izquierda en la ecuación y con un orden de prioridad: por ejemplo, primero los signos de + y - separan terminos, luego *, /, etc...
Para utilizar funciones como log, sen, cos, etc... no se como lo hancen otros programas, porque en su momento no encontré ideas en Internet para resolver este punto. En mi caso, lo que hice fue transformar esos nombres de funciones en operadores para volver a usar el codigo que ya tenia. Es decir, ademas de tener +,-,*,/, invente un operador @, de modo que lo que esta antes del operador identifica a la función a ejecutar y lo que esta después del operador es el valor de entrada para esa función.. Para aclarar este concepto vamos a un ejemplo: el usuario escribe "log 10" y el programa reemplaza una sola vez "log" por "1@", entonces queda "1@10". Cuando en la evaluacion encuentro la operacion @, busco de que funcion se trata. En este caso es la función "1", que es log (por ejemplo, la función exp podria ser 2, raiz cuadrada la 3, etc....). A continuación busco el valor de entrada, que es el segundo operando, en este caso 10 y ejecuto la funcion log de Basic para ese valor mediante un case.

Sin embargo, cuando estamos graficando, resolvemos la misma ecuación cientos de veces. Entonces, ¿porque no guardar el arbol de evaluación, en lugar de hacer uno diferente cada vez? Esto implica hacer una funcion de evaluación específica para graficar, que no es lo que esta en los libros. Lo que ocurre es que generalmente el programador usa codigo de evaluacion bajado de internet y le pone una interfaz grafica para obtener su graficador de funciones. De ahi en mas, simplemente se limitan a invocar el codigo de evaluacion para unos cuantos puntos del grafico, sustituyendo las variables por sus valores e invocando una y otra vez a la función de evaluación.

En mi caso, he realizado una especie de cache de terminos, operaciones y arbol de evaluación, que depende siempre de las variables x, p, etc... Sus valores no se sustuyen hasta el ultimo momento, de modo que se puedan volver a usar esos datos cuando cambian los valores de las variables. Es decir que dejo el arbol de evaluación armado para todos los valores de x, en lugar de generarlo una y otra vez, y  además, como el orden se repite siempre, guardo el resultado de otros calculos y evaluaciones mediante el mismo principio.
Finalmente, al graficar, lo que se hace es evaluar la función para algunos puntos y unirlos, de modo que el usuario pueda ver el grafico en pantalla.

Con respecto al zoom, movimientos de pantalla, zoom a medida, etc... se trata basicamente de la aplicación de formulas de geometria analitica, en particular traslación de ejes y cambio de escalas. Al momento de realizar el grafico en pantalla se hace una conversión de los valores en numeros reales a "twips" o pixels, que son unidades de medida que se usan para medir distancias en pantalla. Para lograr el efecto zoom, basta con alterar esas relaciones, y para mover la pantalla se le suma o resta a los valores minimos y máximos del rango a graficar elegido inicialmente por el usuario.