home *** CD-ROM | disk | FTP | other *** search
- #ifndef __PROC_CPP
- #define __PROC_CPP
- #include "proc.h"
-
- void Cekej(int vypis) {
- if (vypis) cout << "Stiskni klavesu..." << endl;
- while (kbhit()) getch();
- if (getch()==0) getch();
- }
-
- //Funkce je volana pri vypisu prvku seznamu v ET.
- void vypis(T p) {
- cout << "y: " << p.y << " x0: " << p.x0 << " sklon cit: " << p.sklon_cit << " sklon jme: " << p.sklon_jme << endl;
- }
-
- //Globalni data
- int xmin,xmax,ymin,ymax; //nejmensi obdelnik, ve kterem bude cely mnohouhelnik obsazen
- Seznam *et; //ukazatel na tabulku hran ET
- Seznam *aet; //ukazatel na tabulku hran AET
-
- //Nastavi xmin,xmax,ymin,ymax podle aktualniho mnohouhelniku
- void NastavRozmery(int pocet, TBod v[]) {
- TBod b;
- for (int i=0;i<pocet;i++) {
- b=v[i];
- if (b.x<xmin) xmin=b.x;
- if (b.x>xmax) xmax=b.x;
- if (b.y<ymin) ymin=b.y;
- if (b.y>ymax) ymax=b.y;
- }
- }
-
- //Prehozeni obsahu dvou promennych typu int
- void Prehod(int &i1,int &i2) { int p=i1;i1=i2;i2=p; }
-
- //Vykresleni usecky
- void ScanLine(int xmin,int ymin,int xmax,int ymax) {
- //num - numerator - to jest citatel zlomku 1/m = x / y
- //den - denominator - to jest jmenovatel zlomku zlomku 1/m = x / y
- int x,y,inc,num,den;
- if ((xmin>xmax)||(ymin>ymax)) { Prehod(xmin,xmax);Prehod(ymin,ymax); }
- int dx=xmax-xmin;int dy=ymax-ymin;
- num=xmax-xmin;den=ymax-ymin;inc=den;
- if (abs(dy)>abs(dx)) {
- if (dy<0) {Prehod(ymin,ymax);Prehod(xmin,xmax);dx=-dx;}
- x=xmin;dy=abs(dy);den=abs(den);num=abs(num);inc=den;
- if (dx>=0) {
- for(y=ymin;y<ymax;y++) {putpixel(x,y,YELLOW);inc+=num;if (inc>den) {x++;inc-=den;}}
- } else {
- for(y=ymin;y<ymax;y++) {putpixel(x,y,YELLOW);inc+=num;if (inc>den) {x--;inc-=den;}}
- }
- } else {
- if (dx<0) {Prehod(xmin,xmax);Prehod(ymin,ymax);dy=-dy;}
- y=ymin;dx=abs(dx);den=abs(den);num=abs(num);inc=num;
- if (dy>=0) {
- for(x=xmin;x<xmax;x++) {putpixel(x,y,YELLOW);inc+=den;if (inc>num) {y++;inc-=num;}}
- } else {
- for(x=xmin;x<xmax;x++) {putpixel(x,y,YELLOW);inc+=den;if (inc>num) {y--;inc-=num;}}
- }
- }
- }
-
- void TestScanLine() {
- int x0,y0,s0,v0;
- cleardevice();Cekej(1);
- for(x0=100;x0<600;x0+=100) {
- y0=150;s0=30;v0=40;
- ScanLine(x0,y0,x0+2*s0,y0 ); // _
- ScanLine(x0,y0,x0+2*s0,y0- v0); // /
- ScanLine(x0,y0,x0+2*s0,y0-2*v0); // /
- ScanLine(x0,y0,x0+ s0,y0-2*v0); // /
- ScanLine(x0,y0,x0 ,y0-2*v0); // |
- ScanLine(x0,y0,x0- s0,y0-2*v0); // \
- ScanLine(x0,y0,x0-2*s0,y0-2*v0); // \
- ScanLine(x0,y0,x0-2*s0,y0- v0); // \
- ScanLine(x0,y0,x0-2*s0,y0 ); // _
- ScanLine(x0,y0,x0-2*s0,y0+ v0); // /
- ScanLine(x0,y0,x0-2*s0,y0+2*v0); // /
- ScanLine(x0,y0,x0- s0,y0+2*v0); // /
- ScanLine(x0,y0,x0 ,y0+2*v0); // |
- ScanLine(x0,y0,x0+ s0,y0+2*v0); // \
- ScanLine(x0,y0,x0+2*s0,y0+2*v0); // \
- ScanLine(x0,y0,x0+2*s0,y0+ v0); // \
- }
- Cekej(1);
- for(x0=100;x0<600;x0+=100) {
- y0=300;s0=30;v0=40;
- line(x0,y0,x0+2*s0,y0 ); // _
- line(x0,y0,x0+2*s0,y0- v0); // /
- line(x0,y0,x0+2*s0,y0-2*v0); // /
- line(x0,y0,x0+ s0,y0-2*v0); // /
- line(x0,y0,x0 ,y0-2*v0); // |
- line(x0,y0,x0- s0,y0-2*v0); // \
- line(x0,y0,x0-2*s0,y0-2*v0); // \
- line(x0,y0,x0-2*s0,y0- v0); // \
- line(x0,y0,x0-2*s0,y0 ); // _
- line(x0,y0,x0-2*s0,y0+ v0); // /
- line(x0,y0,x0-2*s0,y0+2*v0); // /
- line(x0,y0,x0- s0,y0+2*v0); // /
- line(x0,y0,x0 ,y0+2*v0); // |
- line(x0,y0,x0+ s0,y0+2*v0); // \
- line(x0,y0,x0+2*s0,y0+2*v0); // \
- line(x0,y0,x0+2*s0,y0+ v0); // \
- }
- Cekej(1);cleardevice();
- }
-
- //Vytvori tabulku hran ET
- void VytvoreniET(int pocet, TBod v[]) {
- //vytvoreni ET - ege table
- TBunka b;
- et=new Seznam[ymax-ymin+1]; //prvek tabulky et je v tomto pripade seznam
- if (!et) {cout << "Nedostatek pameti pro vytvoreni tabulky ET" << endl;exit(1);}
- int predchozi,dalsi;
- for(int i=0;i<pocet;i++) {
- if (i>0) predchozi=i-1; else predchozi=pocet-1;
- if (i<pocet-1) dalsi=i+1; else dalsi=0;
- if (v[predchozi].y>v[i].y) /*pridej hranu do seznamu*/ {
- b.y=v[predchozi].y;b.x0=v[i].x;b.sklon_cit=v[predchozi].x-v[i].x;b.sklon_jme=v[predchozi].y-v[i].y;et[v[i].y-ymin].Pridej(b);
- }
- if (v[dalsi].y>v[i].y) /*prideh hranu do seznamu*/ {
- b.y=v[dalsi].y;b.x0=v[i].x;b.sklon_cit=v[dalsi].x-v[i].x;b.sklon_jme=v[dalsi].y-v[i].y;et[v[i].y-ymin].Pridej(b);
- }
- }
- /* for(i=ymin;i<=ymax;i++) {
- printf("%i...",i);et[i-ymin].Vypis();
- }*/
- }
-
- //Vytvoreni tabulky hran AET
- void VytvoreniAET(int pocet, TBod v[]) {
- TBunka b;
- aet=new Seznam[ymax-ymin+1]; //prvek tabulky (pole) aet je v tomto pripade seznam
- if (!aet) {cout << "Nedostatek pameti pro vytvoreni tabulky AET" << endl;exit(1);}
- int dalsi;
- for(int y=ymin;y<=ymax;y++) for(int i=0;i<pocet;i++) {
- if (i<pocet-1) dalsi=i+1; else dalsi=0;
- if ((v[i].y<=y)&&(y<=v[dalsi].y)&&(v[dalsi].y!=v[i].y)) /*prideh hranu do seznamu, pokud neni vodorovna*/ {
- b.y=v[dalsi].y;b.sklon_cit=v[dalsi].x-v[i].x;b.sklon_jme=v[dalsi].y-v[i].y;b.x0=v[i].x+b.sklon_cit*(y-v[i].y)/b.sklon_jme;aet[y-ymin].Pridej(b);
- }
- if ((v[dalsi].y<=y)&&(y<=v[i].y)&&(v[dalsi].y!=v[i].y)) /*prideh hranu do seznamu, pokud neni vodorovna*/ {
- b.y=v[i].y;b.sklon_cit=v[i].x-v[dalsi].x;b.sklon_jme=v[i].y-v[dalsi].y;b.x0=v[dalsi].x+b.sklon_cit*(y-v[dalsi].y)/b.sklon_jme;aet[y-ymin].Pridej(b);
- }
- }
- }
-
- void VypisAET() {
- for(int y=ymin;y<=ymax;y++) {
- cout << y << "..." << endl;aet[y-ymin].Vypis();Cekej();
- }
- }
-
- void OtevriGrafiku() {
- VypisPrvku = vypis;
- int gdriver = DETECT, gmode, errorcode;initgraph(&gdriver,&gmode,"d:\\bc31\\bgi");errorcode=graphresult();
- if (errorcode != grOk) {cout << "Graphics error: " << grapherrormsg(errorcode) << endl << "Press any key to halt:" << endl;Cekej();exit(1);}
- }
-
- void ZavriGrafiku() {
- Cekej();closegraph();
- }
-
- //Bublinkove trideni seznamu s, prvky se tridi podle x v zaznamu
- void SetridSeznam(Seznam &s) {
- int c1,c2,zmeneno;
- T pom;
- if (s.Prazdny()) return;
- if (s.Jednoprvkovy()) return;
- prvek *od,*prv,*dal;
- do {
- od=s.ZjistiPrvni();
- prv=s.ZjistiPrvni();dal=s.ZjistiPrvni()->dalsi;zmeneno=0;
- while (dal!=0) {
- c1=prv->d.x0;c2=dal->d.x0;
- if (c1>c2) {pom=prv->d;prv->d=dal->d;dal->d=pom;zmeneno=1;}
- prv=prv->dalsi;dal=dal->dalsi;
- }
- od=od->dalsi;
- } while (zmeneno);
- }
-
- void SetridAET() {
- for(int i=0;i<=ymax-ymin;i++) {
- SetridSeznam(aet[i]);
- }
- }
-
- int Parita(int x,int y) {
- prvek *prv,*dal;
- int p=0;
- prv=aet[y].ZjistiPrvni();
- while (prv!=0) {
- if (prv->d.x0==x) break;
- prv=prv->dalsi;
- }
- if (prv==0) {cout << "Pro bod " << x << "," << y << " nelze urcit paritu, bod nebyl v tabulce nalezen." << endl;return -1;}
- else {
- while ((prv!=0)&&(prv->d.x0==x)) {
- if (prv->d.y>y) p++;
- prv=prv->dalsi;
- }
- return p;
- }
- }
-
- void Vypln(int pocet, TBod v[],int xposun,int yposun,int barva) {
- int stara=getcolor();setcolor(barva);
- NastavRozmery(pocet,v);VytvoreniET(pocet,v);
- VytvoreniAET(pocet,v);SetridAET();
- prvek *prv;
- int xk; //bod od ktereho se bude kreslit
- int kreslit; //zda-li se kresli prave usecka mezi pruseciky ci nikoli
- for(int y=0;y<=ymax-ymin;y++) {
- if (!aet[y].Prazdny()) {
- kreslit=0;prv=aet[y].ZjistiPrvni();xk=-1;
- while (prv!=0) {
- int x=prv->d.x0;
- if (kreslit) { //pokud kreslime caru
- if (xk!=x) if (Parita(x,y+ymin)%2==1) {line(xk+xposun,y+ymin+yposun,x+xposun,y+ymin+yposun);kreslit=0;}
- } else { //pokud nekreslime caru
- if (Parita(x,y+ymin)%2==1) {xk=x;kreslit=1;}
- } //konec, pokud nekreslime caru
- prv=prv->dalsi;
- }
- }
- }
- delete []et;delete []aet;setcolor(stara);
- }
-
- #endif
-