/* Feito por Vitor Carneiro Maia em 18/10/2008 www.dcc.ufrj.br/~vitormaia Plotador: Este programa desenha gráficos num plano cartesiano. A função drawFunction pode receber como parâmetro funções no formato: double nome(double), ou seja, que recebam um double e retornem um double. Neste exemplo são mostradas as funções seno e cosseno. */ //------------------------------------------------------------------------ // Includes & Namespaces #include #include #include using namespace std; //------------------------------------------------------------------------ // Defines #define MAX_X 800 #define MAX_Y 600 #define V_MAX_X 0 #define V_MAX_Y 0 #define COLOR_BITS 32 #define VIDEO_CARD GFX_AUTODETECT_FULLSCREEN #define DIGI_CARD DIGI_AUTODETECT #define MIDI_CARD MIDI_AUTODETECT //------------------------------------------------------------------------ // Prototypes int begin(void); void closing(void); void loop(void); void drawCoord(void); void drawFunction( double (*f)( double )); void addPoint(double x, double y); //------------------------------------------------------------------------ // Globais BITMAP *buffer; //------------------------------------------------------------------------ int main(int argc, char **argv) { if (!begin()) { closing(); return -1; } buffer = create_bitmap(MAX_X,MAX_Y); loop(); closing(); return 0; } END_OF_MAIN(); int begin(void) { allegro_init(); install_keyboard(); install_mouse(); install_timer(); set_color_depth(COLOR_BITS); if (set_gfx_mode(VIDEO_CARD, MAX_X, MAX_Y, V_MAX_X, V_MAX_Y) < 0) { if (set_gfx_mode(GFX_AUTODETECT, MAX_X, MAX_Y, V_MAX_X, V_MAX_Y) < 0) { allegro_message("Erro ao inicializar o modo grafico"); return (FALSE); } } if (COLOR_BITS == 32) { set_alpha_blender(); } if (install_sound(DIGI_CARD, MIDI_CARD, NULL) < 0) { if (install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL) < 0) { allegro_message("Erro ao inicializar o som"); return (FALSE); } } return (TRUE); } void closing(void) { remove_timer(); remove_mouse(); remove_sound(); remove_keyboard(); allegro_exit(); } //------------------------------------------------------------------------ // As linhas acima devem ser repetidas em todos os programas. void loop(void) { drawCoord(); // drawFunction() recebe uma função por parâmetro. // Chama-se functor, e pode ser feito em C++. drawFunction(sin); drawFunction(cos); do { show_mouse(buffer); blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h); }while(!key[KEY_ESC]); } //------------------------------------------------------------------------ // Funções utilizadas neste exemplo: // Desenha os eixos x e y void drawCoord(void) { hline(buffer, 0, MAX_Y/2, MAX_X, makeacol32(255,255,255,0)); vline(buffer, MAX_X/2, 0, MAX_Y, makeacol32(255,255,255,0)); } // Desenha um gráfico na tela. void drawFunction( double (*f)( double )) { double x = -15; for(double n = x ; n < 15 ; n+=0.01) { addPoint(n,f(n)); } } // Desenha pontos na tela. É usado na função acima. void addPoint(double x, double y) { // Ao ponto x está sendo somado MAX_X/2, e ao y está sendo multiplicado -1 e somado MAX_Y/2. // Estas contas são feitas para acertar o eixo no centro da tela. putpixel(buffer, (int) ((x*30 + MAX_X/2)), (int) ((-y*30 + MAX_Y/2)), makeacol32(0,255,0,0)); } //------------------------------------------------------------------------ float fx(float t, float x, float y) { return x*y + t; } float fy(float t, float x, float y) { return t*x - y; } // Globais: double t0, t1, TM, x0, xa, xb, xc, x1, y0, ya, yb, yc, y1, h, hs2; double r1x, r2x, r3x, r4x, rx, r1y, r2y, r3y, r4y, ry; int N, I; int main(void) { x0 = 1.0; y0 = 2.0; t0 = 0.0; h = 0.1; hs2 = h/2.0; N = 10; I = 0; // Runge-Kutta while(I != N) { I++; r1x = fx(t0,x0,y0); r1y = fy(t0,x0,y0); xa = x0 + r1x * hs2; ya = y0 + r1y * hs2; TM = t0 + hs2; r2x = fx(TM, xa, ya); r2y = fy(TM, xa, ya); xb = x0 + r2x * hs2; yb = y0 + r2y * hs2; r3x = fx(TM,xb,yb); r3y = fy(TM,xb,yb); xc = x0 + r3x * h; yc = y0 + r3y * h; t1 = t0 + h; r4x = fx(t1, xc, yc); r4y = fy(t1,xc,yc); rx = (r1x + 2.0 * r2x + 2.0 * r3x + r4x)/6.0; ry = (r1y + 2.0 * r2y + 2.0 * r3y + r4y)/6.0; x1 = x0 + rx * h; y1 = y0 + ry * h; cout.precision(60); cout << "N = " << N << endl; cout << "t = " << t1 << endl; cout << "x = " << x1 << endl; cout << "y = " << y1 << endl; t0 = t1; x0 = x1; y0 = y1; addPoint(x1,y1); } }