//----------------------------------------------------------------------------- // Fraktaly v pocitacove grafice // Demonstracni priklad 54.2 // Autor: Pavel Tisnovsky // // Vykresleni Hilbertovy krivky pomoci paralelniho prepisovani retezcu. // Po prekladu a spusteni programu se nejprve provede nekolikere rozepsani // gramatiky. Vysledny retezec je posleze pouzit pro vykresleni L-systemu // za pomoci zelvi grafiky (turtle graphics). // Zmena velikosti fraktalu se provadi stiskem klaves [PageUp] a [PageDown], // posun fraktalu je mozne provest kurzorovymi klavesami (sipkami). // Zmena poctu prepisu symbolu se provadi pomoci klaves [1]-[3], pricemz // po stlaceni klavesy [1] je proveden pouze jeden prepis axiomu. // Ukonceni aplikace se provede klavesou [Esc] nebo klavesou [Q]. //----------------------------------------------------------------------------- #ifdef __BORLANDC__ #include #endif #include // hlavickovy soubor funkci GLUTu a OpenGL #include #include #include #include #define WINDOW_TITLE "Fraktaly 54.2" // titulek okna #define WINDOW_WIDTH 400 // pocatecni velikost okna #define WINDOW_HEIGHT 470 #define MAX_LENGTH 500000 // maximalni delka retezce double xpos=0.0; // pozice fraktalu v okne double ypos=0.87*WINDOW_WIDTH/3; char retx[MAX_LENGTH]; // pocatecni symbol int itersCount=1; // pocet aplikaci prepisovaciho pravidla char *rules[]={ // jednotliva prepisovaci pravidla "X=-YF+XFX+FY-", "Y=+XF-YFY-FX+", NULL }; char axiom[]="X"; // axiom - prvotni naplneni vysledneho retezce double step=10;; // krok zelvy double x, y, alpha; // souradnice a natoceni zelvy double delta=3.1415927/2.0; //----------------------------------------------------------------------------- // Aplikace prepisovacich pravidel na retezec //----------------------------------------------------------------------------- void applyRules( char *rules[], // pole prepisovacich pravidel char *axiom, // axiom - prvotni naplneni retezce char *ret, // retezec, do ktereho se ma ulozit vysledek int maxiters) // maximalni pocet iteraci (aplikaci pravidel) { int rulesCount; // pocet pravidel int rule; // prave aplikovane pravidlo char *leftSide; // pole levych casti prepisovacich pravidel char **rightSideSrc; // pole pravych casti prepisovacich pravidel char **rightSideDest; int i, j, k, iter; // pocitadla smycek a indexy znaku // zjistit celkovy pocet prepisovacich pravidel for (rulesCount=0; rules[rulesCount]; rulesCount++) ; // nyni mame v promenne rulesCount ulozen pocet prepisovacich pravidel printf("celkovy pocet pravidel=%d\n", rulesCount); // alokace pameti pro levou stranu prepisovacich pravidel // a inicializace pole znaku leftSide=(char *)malloc(rulesCount*sizeof(char)); for (i=0; i='A' && key<='Z') ? key-'A'+'a': key; // zmena poctu prepsani retezce if (key>='1' && key<='3') { itersCount=key-'1'; // zmena kroku v zavislosti na poctu prepisu //step=WINDOW_WIDTH/(pow(5, itersCount)); initLSystem(itersCount); glutPostRedisplay(); return; } switch (key) { case 27: // pokud byla stlacena klavesa ESC, konec programu case 'q': exit(0); break; // totez co klavesa ESC default: break; } } #ifdef __BORLANDC__ #pragma option -w+par #endif //----------------------------------------------------------------------------- // Tato callback funkce je zavolana pri stlaceni non-ASCII klavesy //----------------------------------------------------------------------------- #ifdef __BORLANDC__ #pragma option -w-par #endif void onSpecial(int key, int x, int y) { // posun fraktalu a zmena meritka switch (key) { case GLUT_KEY_LEFT: xpos-=5; glutPostRedisplay(); break; case GLUT_KEY_RIGHT: xpos+=5; glutPostRedisplay(); break; case GLUT_KEY_UP: ypos+=5; glutPostRedisplay(); break; case GLUT_KEY_DOWN: ypos-=5; glutPostRedisplay(); break; case GLUT_KEY_PAGE_UP: step+=0.5; glutPostRedisplay(); break; case GLUT_KEY_PAGE_DOWN: step-=0.5; glutPostRedisplay(); break; default: break; } } #ifdef __BORLANDC__ #pragma option -w+par #endif //----------------------------------------------------------------------------- // Hlavni funkce konzolove aplikace //----------------------------------------------------------------------------- int main(int argc, char **argv) { glutInit(&argc, argv); // inicializace knihovny GLUT glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutCreateWindow(WINDOW_TITLE); // vytvoreni okna pro kresleni glutReshapeWindow(WINDOW_WIDTH, WINDOW_HEIGHT);// zmena velikosti okna glutPositionWindow(100, 100); // pozice leveho horniho rohu okna glutDisplayFunc(onDisplay); // registrace funkce volane pri prekreslovani okna glutReshapeFunc(onResize); // registrace funkce volane pri zmene velikosti okna glutKeyboardFunc(onKeyboard); // registrace funkce volane pri stlaceni klavesy glutSpecialFunc(onSpecial); // registrace funkce volane pri stlaceni specialni klavesy onInit(); // inicializace vykreslovani glutMainLoop(); // nekonecna smycka, kde se volaji zaregistrovane funkce return 0; // navratova hodnota vracena operacnimu systemu } //----------------------------------------------------------------------------- // finito //-----------------------------------------------------------------------------