DODATEK A Przykładowe program y
Transkrypt
DODATEK A Przykładowe program y
I. Transformacje obiektów 3D. Poni szy program wy wietla na ekranie monitora sfer w rzucie perspektywicznym. W programie zdefiniowane s funkcje pozwalaj ce dokonywa transformacji 3D. #include<graphics.h> #include<math.h> #include<stdio.h> #include<conio.h> #include<iostream.h> #include<stdlib.h> //-------------------------------------------const zakres=35; //liczba katow wielokata (przyblizenie okregu) const d=1000; //odleglosc obserwatora const dzielnik=12; //kat obrotu fi=pi/dzielnik const v=10; //przesuniecie //----------------------------------------------------------------typedef struct {double x; double y; }punkt2D; typedef struct {double x; double y; double z; }punkt3D; punkt3D ttt[zakres+1][zakres+1]; double x0=0; //srodek sfery double y0=0; double z0=0; //------------------------------------------------------------int inicjuj_grafike(int ster, int tryb, char *scster) { initgraph(&ster,&tryb,scster); if(graphresult()!=grOk) { puts("ERROR"); return 0; } else return 1; } //------------------------------------------------------------punkt2D rzutP(punkt3D P) { punkt2D Pprim; Pprim.x=(P.x*d)/(P.z+d)+getmaxx()/2; Pprim.y=0.75*(P.y*d)/(P.z+d)+getmaxy()/2; return Pprim; } //-------------------------------------------------------------void odcinek(punkt2D P1, punkt2D P2) { line(P1.x,P1.y,P2.x,P2.y); } //-----------------------------------------------------------------void punkty_sfery(double r) //r = promien sfery { int i,j; double z,r1; for(i=0;i<=zakres;i++) { z=r*sin(i*(2*M_PI/(zakres+1))); r1=abs(r*cos(i*(2*M_PI/(zakres+1)))); for(j=0;j<=zakres;j++) { ttt[i][j].x=r1*cos(j*(2*M_PI/(zakres+1))); ttt[i][j].y=r1*sin(j*(2*M_PI/(zakres+1))); ttt[i][j].z=z; } } } //-----------------------------------------------------------------void rysuj(int kolor) { int i,j; setcolor(kolor); for(i=0;i<=zakres;i++) { for(j=0;j<zakres;j++) if((ttt[i][j].z+ttt[i][j+1].z)/2<=z0+5) odcinek(rzutP(ttt[i][j]),rzutP(ttt[i][j+1])); if((ttt[i][zakres].z+ttt[i][0].z)/2<=z0+5) odcinek(rzutP(ttt[i][zakres]),rzutP(ttt[i][0])); } for(j=0;j<=zakres;j++) { for(i=0;i<zakres;i++) if((ttt[i][j].z+ttt[i+1][j].z)/2<=z0+5) odcinek(rzutP(ttt[i][j]),rzutP(ttt[i+1][j])); if((ttt[zakres][j].z+ttt[0][j].z)/2<=z0+5) odcinek(rzutP(ttt[zakres][j]),rzutP(ttt[0][j])); } } //-----------------------------------------------------void dol(double v) { int i,j; for(i=0;i<=zakres;i++) for(j=0;j<=zakres;j++) ttt[i][j].y=ttt[i][j].y+v; y0=y0+v; } //-----------------------------------void gora(double v) { int i,j; for(i=0;i<=zakres;i++) for(j=0;j<=zakres;j++) ttt[i][j].y=ttt[i][j].y-v; y0=y0-v; } //-----------------------------------void prawo(double v) { int i,j; for(i=0;i<=zakres;i++) for(j=0;j<=zakres;j++) ttt[i][j].x=ttt[i][j].x+v; x0=x0+v; } //-----------------------------------void lewo(double v) { int i,j; for(i=0;i<=zakres;i++) for(j=0;j<=zakres;j++) ttt[i][j].x=ttt[i][j].x-v; x0=x0-v; } //-----------------------------------void tyl(double v) { int i,j; for(i=0;i<=zakres;i++) for(j=0;j<=zakres;j++) ttt[i][j].z=ttt[i][j].z+v; z0=z0+v; } //-----------------------------------void przod(double v) { int i,j; for(i=0;i<=zakres;i++) for(j=0;j<=zakres;j++) ttt[i][j].z=ttt[i][j].z-v; z0=z0-v; } //-----------------------------------void obrotX(double fi) { int i,j; double temp; for(i=0;i<=zakres;i++) for(j=0;j<=zakres;j++) { temp=ttt[i][j].y; ttt[i][j].y=(temp-y0)*cos(fi)-(ttt[i][j].z-z0)*sin(fi)+y0; ttt[i][j].z=(temp-y0)*sin(fi)+(ttt[i][j].z-z0)*cos(fi)+z0; } } //-----------------------------------void obrotY(double fi) { int i,j; double temp; for(i=0;i<=zakres;i++) for(j=0;j<=zakres;j++) { temp=ttt[i][j].z; ttt[i][j].z=(temp-z0)*cos(fi)-(ttt[i][j].x-x0)*sin(fi)+z0; ttt[i][j].x=(temp-z0)*sin(fi)+(ttt[i][j].x-x0)*cos(fi)+x0; } } //-----------------------------------void obrotZ(double fi) { int i,j; double temp; for(i=0;i<=zakres;i++) for(j=0;j<=zakres;j++) { temp=ttt[i][j].x; ttt[i][j].x=(temp-x0)*cos(fi)-(ttt[i][j].y-y0)*sin(fi)+x0; ttt[i][j].y=(temp-x0)*sin(fi)+(ttt[i][j].y-y0)*cos(fi)+y0; } } //-----------------------------------void info() //sterowanie { setcolor(DARKGRAY); setfillstyle(1,LIGHTGRAY); bar(0,getmaxy()-30,getmaxx(),getmaxy()); outtextxy(10,getmaxy()-20,"Sterowanie: "); line(130,getmaxy()-15,140,getmaxy()-15); //lewo line(130,getmaxy()-15,133,getmaxy()-17); line(130,getmaxy()-15,133,getmaxy()-13); line(150,getmaxy()-25,150,getmaxy()-18); //gora line(150,getmaxy()-25,148,getmaxy()-23); line(150,getmaxy()-25,152,getmaxy()-23); line(150,getmaxy()-5,150,getmaxy()-12); //dol line(150,getmaxy()-5,148,getmaxy()-7); line(150,getmaxy()-5,152,getmaxy()-7); line(160,getmaxy()-15,170,getmaxy()-15); //prawo line(170,getmaxy()-15,167,getmaxy()-17); line(170,getmaxy()-15,167,getmaxy()-13); outtextxy(190,getmaxy()-20,"[+]"); outtextxy(220,getmaxy()-20,"[-]"); outtextxy(250,getmaxy()-20,"[X]"); outtextxy(280,getmaxy()-20,"[Y]"); outtextxy(310,getmaxy()-20,"[Z]"); outtextxy(380,getmaxy()-20,"[Inny] = STOP"); outtextxy(520,getmaxy()-20,"[Esc] = KONIEC"); } //------------------------------------int main(void) { int s=0; int s2,s1=1; char z='\0'; if(!inicjuj_grafike(VGA,VGAMED,"BGI")) return 0; punkty_sfery(150); rysuj(GREEN); while(z!='\33') { while(!kbhit()) { s2=s;s=s1;s1=s2; setactivepage(s); clearviewport(); switch(z) { case '\120': { dol(v); break;} case '\110': { gora(v); break;} case '\115': { prawo(v); break;} case '\113': { lewo(v); break;} case '+' : { przod(v); break;} case '-' : { tyl(v); break;} case 'x' : { obrotX(M_PI/dzielnik); break;} case 'y' : { obrotY(M_PI/dzielnik); break;} case 'z' : { obrotZ(M_PI/dzielnik); break;} } rysuj(GREEN); info(); setvisualpage(s); } z=getch(); if(z=='\0') z=getch(); } closegraph(); return 0; } II. Fraktale. Zbiory Julii (Gaston Julia, 1893 – 1978). Zbiory Julii znajduj si na płaszczy nie zespolonej i stanowi podstaw do zrozumienia iteracji wielomianów, takich jak z2 + c, albo z3 + c itp. W przedstawionym ni ej programie, dla ustalonej liczby zespolonej c iterujemy wielomian z2+c podstawiaj c w miejsce zmiennej z punkty z kwadratu [-1.5,1.5] ×[-1.5,1.5] na płaszczy nie zespolonej (w ogólnym przypadku rozpatrujemy cał płaszczyzn zespolon ). Dla ka dego z otrzymujemy ci g: z z2 + c (z2 + c)2 + c ((z2 + c)2 + c)2 + c ... Taki ci g b dzie ograniczony lub nieograniczony. Je li jest nieograniczony, to od pewnego miejsca elementy ci gu "opuszcz " ka de koło o rodku w punkcie (0,0). Je li ci g jest ograniczony, to istnieje koło o rodku w punkcie (0,0), którego elementy ci gu nigdy nie opuszcz . Zbiór punktów z, dla których otrzymamy ci g nieograniczony nazywamy zbiorem uciekinierów, a zbiór tych punktów z, dla których otrzymamy ci g ograniczony nazywamy zbiorem wi niów. Oba zbiory pokrywaj pewn cz płaszczyzny zespolonej i dopełniaj si wzajemnie. Granica zbioru wi niów jest jednocze nie granic zbioru uciekinierów, i j wła nie nazywamy zbiorem Julii (dla danego c lub z2 + c). Dla ka dego z z kwadratu [-1.5,1.5] × [-1.5,1.5], sprawdzamy jak szybko wyrazy ci gu "uciekaj " z koła o rodku (0,0) i promieniu 10. Szybko oznacza tutaj liczb iteracji po jakiej kolejne wyrazy ci gu b d poza kołem (im mniejsza liczba iteracji, tym szybciej wyrazy ci gu "uciekaj " z koła). W zale no ci od szybko ci "ucieczki" punkt jest rysowany na ekranie w odpowiednim kolorze. Kwadratowi [-1.5,1.5] ×[-1.5,1.5] odpowiada na ekranie kwadrat 300×300 pikseli. Przyjmujemy, e punkt (0,0)znajduje si na rodku ekranu. Obraz otrzymany na ekranie b dzie zale ał od wybranej liczby c. Poni szy program wy wietla na ekranie monitora przybli enie zbiorów Julii (dla wybranych dziesi ciu warto ci liczby c). #include<conio.h> #include<stdio.h> #include<graphics.h> #include<math.h> #include<complex.h> complex z; complex c[10]; int x,y; //-------------------------------------------------------------int inicjuj_grafike(int ster, int tryb, char *scster) { initgraph(&ster,&tryb,scster); if(graphresult()!=grOk) { puts("ERROR"); return 0; } else return 1; } //-------------------------------------------------------------void liczby_c() { c[0]=complex(0.5,0.5); c[1]=complex(0.4,0.3); c[2]=complex(0.4,-0.3); c[3]=complex(0.25,0.7); c[4]=complex(0.7,-0.25); c[5]=complex(0.3,0.1); c[6]=complex(0.3,-0.1); c[7]=complex(0.3,-0.5); c[8]=complex(0.4,-0.2); c[9]=complex(0.4,-0.4); } //----------------------------------------------------------void info() { setcolor(LIGHTGRAY); setfillstyle(1,DARKGRAY); bar(10,getmaxy()-20,getmaxx(),getmaxy()); setfillstyle(1,BLUE); bar(0,getmaxy()-30,getmaxx()-10,getmaxy()-7); outtextxy(40,getmaxy()-22,"[Spacja] = DALEJ"); outtextxy(420,getmaxy()-22,"[Esc] = KONIEC"); } //----------------------------------------------------------int main(void) { int l,x_srodek,y_srodek; char znak; liczby_c(); if(!inicjuj_grafike(DETECT,0,"BGI")) return 1; info(); x_srodek=getmaxx()/2; y_srodek=getmaxy()/2; setviewport(0,0,getmaxx(),getmaxy()-31,1); for(int i=0;i<10;i++) { for(x=-150;x<=150;x++) for(y=-150;y<=150;y++) { z=complex(0.01*x,0.01*y); // 100 pikseli = jednostka l=0; while((l<101)&&(abs(z)<10)) // iteruje dopoki punkt z nie "ucieknie" { // z kola o promieniu 10 l++; // lub liczba iteracji nie przekroczy 100 z=z*z+c[i]; } if(l>100 ) putpixel(x+x_srodek,y_srodek-y,RED); else if(l>60 ) putpixel(x+x_srodek,y_srodek-y,LIGHTRED); else if(l>45 ) putpixel(x+x_srodek,y_srodek-y,GREEN); else if(l>30 ) putpixel(x+x_srodek,y_srodek-y,LIGHTGREEN); else if(l>20 ) putpixel(x+x_srodek,y_srodek-y,BLUE); else if(l>15) putpixel(x+x_srodek,y_srodek-y,LIGHTBLUE); else if(l>10) putpixel(x+x_srodek,y_srodek-y,YELLOW); else if(l>7) putpixel(x+x_srodek,y_srodek-y,DARKGRAY); } do znak=getch(); while((znak!=32)&&(znak!=27)); if(znak==27) break; clearviewport(); } closegraph(); return 0; } III. Fraktale. Zbiory Mandelbrota (Benoit Mandelbrot). Zbiory Mandelbrota znajduj si na płaszczy nie zespolonej. Podobnie jak zbiory Julii, zbiory Mandelbrota powstaj w wyniku iteracji wielomianów zespolonych np. z2 + c, albo z3 + c itp. W tym przypadku iterujemy dany wielomian dla ustalonej wyj ciowej warto ci zmiennej z, natomiast w miejsce liczby c wstawiamy punkty z płaszczyzny zespolonej. W przedstawionym ni ej programie, dla liczb zespolonych c z prostok ta [-2.5,2.5] × [-1.5,1.5] na płaszczy nie zespolonej iterujemy wielomian z2 + c podstawiaj c pocz tkow warto z = 0 + i0. Otrzymujemy ci g: z z2 + c (z2 + c)2 + c ((z2 + c)2 + c)2 + c ... Sprawdzamy jak szybko wyrazy ci gu "uciekaj " z koła o rodku (0,0) i promieniu 10. Szybko oznacza tutaj liczb iteracji po jakiej kolejne wyrazy ci gu znajd si poza kołem (im mniejsza liczba iteracji, tym szybciej ci g "ucieka" z koła). W zale no ci od szybko ci "ucieczki" rysujemy na ekranie punkt c w odpowiednim kolorze. Prostok towi [-2.5,2.5] × [-1.5,1.5] odpowiada na ekranie prostok t 500×300 pikseli. Przyjmujemy, e punkt (0,0) znajduje si w rodku ekranu. Punkty narysowane kolorem czarnym obrazuj przybli enie zbioru Mandelbrota. B d to te punkty c z prostok ta [-2.5,2.5] ×[-1.5,1.5], dla których wyrazy ci gu nie opuszcz koła po 1000 iteracjach. #include<conio.h> #include<stdio.h> #include<graphics.h> #include<math.h> #include<complex.h> complex z; complex c; int x,y; //--------------------------------------------------------int inicjuj_grafike(int ster, int tryb, char *scster) { initgraph(&ster,&tryb,scster); if(graphresult()!=grOk) { puts("ERROR"); return 0; } else return 1; } //---------------------------------------------------------void info() { setcolor(LIGHTGRAY); setfillstyle(1,DARKGRAY); bar(10,getmaxy()-20,getmaxx(),getmaxy()); setfillstyle(1,BLUE); bar(0,getmaxy()-30,getmaxx()-10,getmaxy()-7); outtextxy(220,getmaxy()-22,"[Esc] = KONIEC"); } //-------------------------------------------------------------int main(void) { int l,x_srodek,y_srodek; char znak; if(!inicjuj_grafike(DETECT,0,"BGI")) return 1; info(); setcolor(CYAN); settextstyle(4,0,4); outtextxy(40,10,"Zbi˘r Mandelbrota (kolorem czarnym)"); x_srodek=getmaxx()/2; y_srodek=getmaxy()/2; for(x=-250;x<=250;x++) for(y=-150;y<=150;y++) { z=complex(0.0,0.0); c=complex(0.01*x,0.01*y); // 100 pikseli = jednostka l=0; while((l<1001)&&(abs(z)<10)) // iteruje dopoki punkt z nie "ucieknie" { // z kola o promieniu 10 l++; // lub liczba iteracji nie przekroczy 100 z=z*z+c; } if(l>1000 ) putpixel(x+x_srodek,y_srodek-y,BLACK); else if(l>60 ) putpixel(x+x_srodek,y_srodek-y,RED); else if(l>40 ) putpixel(x+x_srodek,y_srodek-y,LIGHTRED); else if(l>30 ) putpixel(x+x_srodek,y_srodek-y,GREEN); else if(l>15 ) putpixel(x+x_srodek,y_srodek-y,LIGHTGREEN); else if(l>10) putpixel(x+x_srodek,y_srodek-y,BLUE); else if(l>7) putpixel(x+x_srodek,y_srodek-y,LIGHTCYAN); else if(l>5) putpixel(x+x_srodek,y_srodek-y,YELLOW); } do znak=getch(); while(znak!=27); closegraph(); return 0; }