home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 March / Chip_2002-03_cd1.bin / chplus / cecko / CPP / VYPLN.ZIP / PROC.CPP next >
Encoding:
C/C++ Source or Header  |  1980-01-04  |  7.4 KB  |  231 lines

  1. #ifndef __PROC_CPP
  2. #define __PROC_CPP
  3. #include "proc.h"
  4.  
  5. void Cekej(int vypis) {
  6.  if (vypis) cout << "Stiskni klavesu..." << endl;
  7.  while (kbhit()) getch();
  8.  if (getch()==0) getch();
  9. }
  10.  
  11. //Funkce je volana pri vypisu prvku seznamu v ET.
  12. void vypis(T p) {
  13.  cout << "y: " << p.y << " x0: " << p.x0 << " sklon cit: " << p.sklon_cit << " sklon jme: " << p.sklon_jme << endl;
  14. }
  15.  
  16. //Globalni data
  17. int xmin,xmax,ymin,ymax; //nejmensi obdelnik, ve kterem bude cely mnohouhelnik obsazen
  18. Seznam *et; //ukazatel na tabulku hran ET
  19. Seznam *aet; //ukazatel na tabulku hran AET
  20.  
  21. //Nastavi xmin,xmax,ymin,ymax podle aktualniho mnohouhelniku
  22. void NastavRozmery(int pocet, TBod v[]) {
  23.  TBod b;
  24.  for (int i=0;i<pocet;i++) {
  25.   b=v[i];
  26.   if (b.x<xmin) xmin=b.x;
  27.   if (b.x>xmax) xmax=b.x;
  28.   if (b.y<ymin) ymin=b.y;
  29.   if (b.y>ymax) ymax=b.y;
  30.  }
  31. }
  32.  
  33. //Prehozeni obsahu dvou promennych typu int
  34. void Prehod(int &i1,int &i2) { int p=i1;i1=i2;i2=p; }
  35.  
  36. //Vykresleni usecky
  37. void ScanLine(int xmin,int ymin,int xmax,int ymax) {
  38.  //num - numerator - to jest citatel zlomku 1/m = x / y
  39.  //den - denominator - to jest jmenovatel zlomku zlomku 1/m = x / y
  40.  int x,y,inc,num,den;
  41.  if ((xmin>xmax)||(ymin>ymax)) { Prehod(xmin,xmax);Prehod(ymin,ymax); }
  42.  int dx=xmax-xmin;int dy=ymax-ymin;
  43.  num=xmax-xmin;den=ymax-ymin;inc=den;
  44.  if (abs(dy)>abs(dx)) {
  45.   if (dy<0) {Prehod(ymin,ymax);Prehod(xmin,xmax);dx=-dx;}
  46.   x=xmin;dy=abs(dy);den=abs(den);num=abs(num);inc=den;
  47.   if (dx>=0) {
  48.    for(y=ymin;y<ymax;y++) {putpixel(x,y,YELLOW);inc+=num;if (inc>den) {x++;inc-=den;}}
  49.   } else {
  50.    for(y=ymin;y<ymax;y++) {putpixel(x,y,YELLOW);inc+=num;if (inc>den) {x--;inc-=den;}}
  51.   }
  52.  } else {
  53.   if (dx<0) {Prehod(xmin,xmax);Prehod(ymin,ymax);dy=-dy;}
  54.   y=ymin;dx=abs(dx);den=abs(den);num=abs(num);inc=num;
  55.   if (dy>=0) {
  56.    for(x=xmin;x<xmax;x++) {putpixel(x,y,YELLOW);inc+=den;if (inc>num) {y++;inc-=num;}}
  57.   } else {
  58.    for(x=xmin;x<xmax;x++) {putpixel(x,y,YELLOW);inc+=den;if (inc>num) {y--;inc-=num;}}
  59.   }
  60.  }
  61. }
  62.  
  63. void TestScanLine() {
  64.  int x0,y0,s0,v0;
  65.  cleardevice();Cekej(1);
  66.  for(x0=100;x0<600;x0+=100) {
  67.  y0=150;s0=30;v0=40;
  68.  ScanLine(x0,y0,x0+2*s0,y0     ); // _
  69.  ScanLine(x0,y0,x0+2*s0,y0-  v0); // /
  70.  ScanLine(x0,y0,x0+2*s0,y0-2*v0); // /
  71.  ScanLine(x0,y0,x0+  s0,y0-2*v0); // /
  72.  ScanLine(x0,y0,x0     ,y0-2*v0); // |
  73.  ScanLine(x0,y0,x0-  s0,y0-2*v0); // \
  74.  ScanLine(x0,y0,x0-2*s0,y0-2*v0); // \
  75.  ScanLine(x0,y0,x0-2*s0,y0-  v0); // \
  76.  ScanLine(x0,y0,x0-2*s0,y0     ); // _
  77.  ScanLine(x0,y0,x0-2*s0,y0+  v0); // /
  78.  ScanLine(x0,y0,x0-2*s0,y0+2*v0); // /
  79.  ScanLine(x0,y0,x0-  s0,y0+2*v0); // /
  80.  ScanLine(x0,y0,x0     ,y0+2*v0); // |
  81.  ScanLine(x0,y0,x0+  s0,y0+2*v0); // \
  82.  ScanLine(x0,y0,x0+2*s0,y0+2*v0); // \
  83.  ScanLine(x0,y0,x0+2*s0,y0+  v0); // \
  84.  }
  85.  Cekej(1);
  86.  for(x0=100;x0<600;x0+=100) {
  87.  y0=300;s0=30;v0=40;
  88.  line(x0,y0,x0+2*s0,y0     ); // _
  89.  line(x0,y0,x0+2*s0,y0-  v0); // /
  90.  line(x0,y0,x0+2*s0,y0-2*v0); // /
  91.  line(x0,y0,x0+  s0,y0-2*v0); // /
  92.  line(x0,y0,x0     ,y0-2*v0); // |
  93.  line(x0,y0,x0-  s0,y0-2*v0); // \
  94.  line(x0,y0,x0-2*s0,y0-2*v0); // \
  95.  line(x0,y0,x0-2*s0,y0-  v0); // \
  96.  line(x0,y0,x0-2*s0,y0     ); // _
  97.  line(x0,y0,x0-2*s0,y0+  v0); // /
  98.  line(x0,y0,x0-2*s0,y0+2*v0); // /
  99.  line(x0,y0,x0-  s0,y0+2*v0); // /
  100.  line(x0,y0,x0     ,y0+2*v0); // |
  101.  line(x0,y0,x0+  s0,y0+2*v0); // \
  102.  line(x0,y0,x0+2*s0,y0+2*v0); // \
  103.  line(x0,y0,x0+2*s0,y0+  v0); // \
  104.  }
  105.  Cekej(1);cleardevice();
  106. }
  107.  
  108. //Vytvori tabulku hran ET
  109. void VytvoreniET(int pocet, TBod v[]) {
  110.  //vytvoreni ET - ege table
  111.  TBunka b;
  112.  et=new Seznam[ymax-ymin+1]; //prvek tabulky et je v tomto pripade seznam
  113.  if (!et) {cout << "Nedostatek pameti pro vytvoreni tabulky ET" << endl;exit(1);}
  114.  int predchozi,dalsi;
  115.  for(int i=0;i<pocet;i++) {
  116.   if (i>0) predchozi=i-1; else predchozi=pocet-1;
  117.   if (i<pocet-1) dalsi=i+1; else dalsi=0;
  118.   if (v[predchozi].y>v[i].y) /*pridej hranu do seznamu*/ {
  119.    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);
  120.   }
  121.   if (v[dalsi].y>v[i].y) /*prideh hranu do seznamu*/ {
  122.    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);
  123.   }
  124.  }
  125. /* for(i=ymin;i<=ymax;i++) {
  126.   printf("%i...",i);et[i-ymin].Vypis();
  127.  }*/
  128. }
  129.  
  130. //Vytvoreni tabulky hran AET
  131. void VytvoreniAET(int pocet, TBod v[]) {
  132.  TBunka b;
  133.  aet=new Seznam[ymax-ymin+1]; //prvek tabulky (pole) aet je v tomto pripade seznam
  134.  if (!aet) {cout << "Nedostatek pameti pro vytvoreni tabulky AET" << endl;exit(1);}
  135.  int dalsi;
  136.  for(int y=ymin;y<=ymax;y++) for(int i=0;i<pocet;i++) {
  137.   if (i<pocet-1) dalsi=i+1; else dalsi=0;
  138.   if ((v[i].y<=y)&&(y<=v[dalsi].y)&&(v[dalsi].y!=v[i].y)) /*prideh hranu do seznamu, pokud neni vodorovna*/ {
  139.    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);
  140.   }
  141.   if ((v[dalsi].y<=y)&&(y<=v[i].y)&&(v[dalsi].y!=v[i].y)) /*prideh hranu do seznamu, pokud neni vodorovna*/ {
  142.    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);
  143.   }
  144.  }
  145. }
  146.  
  147. void VypisAET() {
  148.  for(int y=ymin;y<=ymax;y++) {
  149.   cout << y << "..." << endl;aet[y-ymin].Vypis();Cekej();
  150.  }
  151. }
  152.  
  153. void OtevriGrafiku() {
  154.  VypisPrvku = vypis;
  155.  int gdriver = DETECT, gmode, errorcode;initgraph(&gdriver,&gmode,"d:\\bc31\\bgi");errorcode=graphresult();
  156.  if (errorcode != grOk) {cout << "Graphics error: " << grapherrormsg(errorcode) << endl << "Press any key to halt:" << endl;Cekej();exit(1);}
  157. }
  158.  
  159. void ZavriGrafiku() {
  160.  Cekej();closegraph();
  161. }
  162.  
  163. //Bublinkove trideni seznamu s, prvky se tridi podle x v zaznamu
  164. void SetridSeznam(Seznam &s) {
  165.  int c1,c2,zmeneno;
  166.  T pom;
  167.  if (s.Prazdny()) return;
  168.  if (s.Jednoprvkovy()) return;
  169.  prvek *od,*prv,*dal;
  170.  do {
  171.   od=s.ZjistiPrvni();
  172.   prv=s.ZjistiPrvni();dal=s.ZjistiPrvni()->dalsi;zmeneno=0;
  173.   while (dal!=0) {
  174.    c1=prv->d.x0;c2=dal->d.x0;
  175.    if (c1>c2) {pom=prv->d;prv->d=dal->d;dal->d=pom;zmeneno=1;}
  176.    prv=prv->dalsi;dal=dal->dalsi;
  177.   }
  178.   od=od->dalsi;
  179.  } while (zmeneno);
  180. }
  181.  
  182. void SetridAET() {
  183.  for(int i=0;i<=ymax-ymin;i++) {
  184.   SetridSeznam(aet[i]);
  185.  }
  186. }
  187.  
  188. int Parita(int x,int y) {
  189.  prvek *prv,*dal;
  190.  int p=0;
  191.  prv=aet[y].ZjistiPrvni();
  192.  while (prv!=0) {
  193.   if (prv->d.x0==x) break;
  194.   prv=prv->dalsi;
  195.  }
  196.  if (prv==0) {cout << "Pro bod " << x << "," << y << " nelze urcit paritu, bod nebyl v tabulce nalezen." << endl;return -1;}
  197.  else {
  198.   while ((prv!=0)&&(prv->d.x0==x)) {
  199.    if (prv->d.y>y) p++;
  200.    prv=prv->dalsi;
  201.   }
  202.   return p;
  203.  }
  204. }
  205.  
  206. void Vypln(int pocet, TBod v[],int xposun,int yposun,int barva) {
  207.  int stara=getcolor();setcolor(barva);
  208.  NastavRozmery(pocet,v);VytvoreniET(pocet,v);
  209.  VytvoreniAET(pocet,v);SetridAET();
  210.  prvek *prv;
  211.  int xk; //bod od ktereho se bude kreslit
  212.  int kreslit; //zda-li se kresli prave usecka mezi pruseciky ci nikoli
  213.  for(int y=0;y<=ymax-ymin;y++) {
  214.   if (!aet[y].Prazdny()) {
  215.    kreslit=0;prv=aet[y].ZjistiPrvni();xk=-1;
  216.    while (prv!=0) {
  217.     int x=prv->d.x0;
  218.     if (kreslit) { //pokud kreslime caru
  219.      if (xk!=x) if (Parita(x,y+ymin)%2==1) {line(xk+xposun,y+ymin+yposun,x+xposun,y+ymin+yposun);kreslit=0;}
  220.     } else { //pokud nekreslime caru
  221.      if (Parita(x,y+ymin)%2==1) {xk=x;kreslit=1;}
  222.     } //konec, pokud nekreslime caru
  223.     prv=prv->dalsi;
  224.    }
  225.   }
  226.  }
  227.  delete []et;delete []aet;setcolor(stara);
  228. }
  229.  
  230. #endif
  231.