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;
}

Podobne dokumenty