Código En C++ Para Dibujar Funciones Matemáticas

Hola, uno de los grandes problemas que tenemos los matemáticos cuando programamos en C/C++ es poder dibujar las funciones matemáticas que podamos estar utilizando en nuestros códigos. Podríamos solucionarlo utilizando las librerías OpenGL o algunas del mismo corte, estas están bien para funciones en 2D y sin utilizar muchas florituras, pero si pasamos a 3D se hacen bastante difíciles la creación de nuestros códigos; además de ralentizar su funcionamiento. Así que utilizando Ubuntu y conociendo la existencia del programa gnuplot ( que se ejecuta por terminal) pensé si sería posible abrirlo desde un programa que estemos escribiendo en C/C++.
Como desde hace años todo lo que aprendo de C++ es por internet, libros, amigos ( autodidacta) pensé buscar en internet información sobre ello o algún código ya hecho. Resultó que había bastante información del tema, mucha de ella eran códigos escritos en C, muy largos y farragosos. La mayoría utilizaban la función popen(), la cual desconocía (( ya mencioné que soy autodidacta )) . Seguí buscando y al final encontré en un foro una cita sobre un código escrito por alguien de habla Shaekesperiana que había escrito el código en C++ utilizando clases y para Linux. El enlace en cuestión es en Foros Del Web.

Pensé que si funcionaba sería genial, ya que aparte de tener un código escrito en C++, lo podría tener en formato de clases y, no sólo eso, sino que además me permitiría escribir un archivo .h y otro .cpp para utilizarlos con la llamada include para futuros programas que realices, sin tener que reescribir cada vez todo el código. Así que a ratitos he ido modificando el código, que podéis ver en el enlace antes mentado, para que haga lo que yo quiero.
He de aclarar que el código que he hecho no está basado en librerías GTK, QT o similares. El programa cuando lo ejecuto se ejecuta, valga la redundancia, en una terminal. Aunque para mi parecer ésta es la forma más cómoda y eficaz de aprender C/C++, los GUIS siempre me resultan pesados y enrevesados.
Bueno sin más escribo aquí el código en cuestión, el código se compone de tres ficheros, el primero le he llamado gnuplot.h y contiene la declaración de la clase GNUplot, sus funciones y variables miembro:

  1. #ifndef GNUPLOT_H_
  2. #define GNUPLOT_H_
  3.  
  4. #include <iostream>
  5.  
  6. using namespace std;
  7.  
  8. class GNUplot
  9. {
  10.  public:
  11.   GNUplot() throw(string);
  12.   ~GNUplot();
  13.   void operator ()(const string& command);
  14.  
  15. protected:
  16.   FILE *gnuplotpipe;
  17.  
  18. };
  19. #endif /*GNUPLOT_H_*/

Después tengo el fichero gnuplot.cpp que consta del código que tienen cada una de las funciones miembro de la clase GNUplot y que se han declarado anteriormente en gnuplot.h

  1. #include <iostream>
  2. #include <string>
  3. #include "gnuplot.h"
  4.  
  5. using namespace std;
  6.  
  7. GNUplot::GNUplot() throw(string)
  8. {
  9.  gnuplotpipe=popen("gnuplot -persist","w");
  10.  if (!gnuplotpipe) {
  11.  throw("¡ No se encontro GNUPLOT!");
  12.  }
  13. }
  14.  
  15. GNUplot::~GNUplot()
  16. {
  17.  fprintf(gnuplotpipe,"exit\n");
  18.  pclose(gnuplotpipe);
  19. }
  20.  
  21. void GNUplot::operator() (const string& command)
  22. {
  23.  fprintf(gnuplotpipe,"%s\n",command.c_str());
  24.  fflush(gnuplotpipe);
  25.  // fflush es necesario para poder dibujar
  26. }

Quiero hacer hincapié en algo muy importante en este fichero, y es que en estos ficheros en los que el código lo único que hace es especificar las instrucciones de nuestra clase (antes declarada con un .h) nunca declaréis la función main(), y mucho menos si lo queréis utilizar en otros futuros programas. Para eso ya tenéis la oportunidad de crearos otro fichero .cpp que contenga la declaración de main(), como es el caso del fichero que he llamado dibujar.cpp y que de código es:

  1. #include <iostream>
  2. #include <string>
  3. #include "gnuplot.h"
  4.  
  5. using namespace std;
  6.  
  7. int main(int argc, char** argv)
  8. {
  9.     GNUplot plotter;
  10.     string comando;
  11.     cout<<"Introduce la orden gnuplot a ejecutar:"<<endl;
  12.     getline(cin,comando);
  13.     plotter(comando);
  14.     return 0;
  15. }

Bueno como veis en dibujar.cpp declaramos un include hacia la librería gnuplot.h que hemos creado por nuestra cuenta. Además éste es el cuerpo de nuestro fichero principal de nuestro programa, en el cual ya declaramos la función principal main() y lo mque queremos que se realice en nuestro programa. En este programa lo que se hará es que por terminal introduciremos una orden o conjunto de órdenes de gnuplot y el programa al llegar a la instrucción plotter(comando) nos abrirá gnuplot, realizará lo que le hemos mandado y si lo que le hemos mandado posee algún error de sintaxis el programa nos informará de ello.
Con éste simple código y un poco más allá podríamos crear nuestro gnuplotgtk.

Bueno para que vaya el programa deberéis tener instalado gnuplot en vuestro S.O., los de Ubuntu y derivados lo encontraréis en Synaptic.

Para compilar el programa y ejecutarlo lo podéis hacer por terminal escribiendo:

g++ gnuplot.cpp dibujar.cpp -o dibujar
./dibujar

También lo podéis escribir, compilar y ejecutar fácilmente con EasyEclipse para C/C++ Por ejemplo si al ejecutarlo escribimos el siguiente conjunto de órdenes:

set xrange [-2:2]; set yrange [-2:2]; set pm3d; splot exp(-x*x)*exp(-y*y); set term postscript eps enhanced color; set output ‘/home/crislosi/color.eps’; replot

Obtendremos la siguiente gráfica, además nos guardará la gráfica en formato Postscript (.eps) en /home/crislosi con nombre color.eps, así la podremos añadir fácilmente con Lyx a nuestros documentos escritos con Latex.

ImageShack

Para escribir un conjunto de órdenes basta escribirlas en una misma línea separadas por punto y coma y un espacio.
A ver si saco tiempo y hago un gnuplotgtk

Saludos

Enlace-> Tutorial de Gnuplot

8 Responses to“Código En C++ Para Dibujar Funciones Matemáticas”

  1. 6 mayo, 2008 at 19:31 #

    valen verga tods los de este progrma

  2. Luis Sánchez
    26 mayo, 2008 at 23:19 #

    Estimado Cristobal, he probado el codigo que escribes y me funciona muy bien, el unico detalle es que no puedo activar el zoom sobre la grafica, entonces mi preguta es: ¿el no poder activar el zoom sobre la grafica se debe a un probrema en mi maquina o es la forma en que el programa funciona? Gracias, de todos modos me ha servido muchisimo.

  3. 28 mayo, 2008 at 10:05 #

    Hola Luis lo del zoom se debe a gnuplot, no se si tiene un comando para zoom, pero si lo tiene se lo debes añadir a la orden que le mandas hacer por terminal. Deberás buscar en el manual de gnuplot, pero dudo que haya zoom, lo que habrá es cambios de escala.
    Me alegra que te haya servido el código
    Casi no tengo tiempo para programar, a ver si este verano cuando acabe las opos me pongo a ello.
    Saludos

  4. melicertes
    16 septiembre, 2008 at 0:32 #

    ola ayudenme mi paquete que instalelde dev c++ no abre la consola de graficos.logro emcontrar algo para ayudar a mi paquete pero no se como usarlo . ok adios cibernautas

  5. katty
    10 diciembre, 2008 at 2:24 #

    porfavor alguien me puede decir como hacer un dibujo en c++
    el dibujo es de bart simpson.. :-SS ~X(

  6. 20 marzo, 2009 at 23:37 #

    mi programa Dev-C++ tiene un error de compilacion que es este:

    g++ gnuplot.cpp dibujar.cpp -o dibujar./dibujar

    me podrias ayudar??

  7. ica
    24 marzo, 2010 at 5:19 #

    Muy Buen tutorial te felicito nuevamente, quisiera saber si de casualidad no tienes entre tus codigos alguno que me permita empotrar gnuplot dentro de una interfaz de wxwidgets. Saludos.

  8. MAURICIO RODRIGUEZ
    23 septiembre, 2010 at 14:34 #

    Impresionante trabajo. Muchas Gracias

Comments are closed.

Proudly powered by WordPress   Premium Style Theme by www.gopiplus.com