// (c) Dinko Korunic, 36355514, kreator@fly.srk.fer.hr // Zadatak broj 3 iz predmeta Racunalna grafika #include #include #include #include class MyDisplay { // klasa MyDisplay u kojoj se nalaze inicijalizacijske xlib // rutine, kao i postavljanje background i foreground boje, itd. XGCValues gcv; unsigned long wp, bp; int screen, winx, winy, winsx, winsy; public: Display *disp; Window win; GC gc; XEvent ev; MyDisplay(int _winx, int _winy, int _winsx, int _winsy); ~MyDisplay(); }; MyDisplay::MyDisplay(int _winx=0, int _winy=0, int _winsx=400, int _winsy=400) : winx(_winx), winy(_winy), winsx(_winsx), winsy(_winsy) { // konstruktor koji sluzi za misc. inicijalizaciju cout << "Initialising graphic subsystem.." << endl; // otvaranje displaya if ((disp=XOpenDisplay(NULL))==NULL) { cerr << "I can't open display." << endl; exit(EXIT_FAILURE); } screen=DefaultScreen(disp); // stvaranje prototipnog prozora win=XCreateSimpleWindow(disp, DefaultRootWindow(disp), winx, winy, winsx, winsy, 1, wp=WhitePixel(disp, screen), bp=BlackPixel(disp, screen)); XSelectInput(disp, win, StructureNotifyMask | KeyPressMask | ExposureMask); // mapiranje prozora XMapWindow(disp, win); while(1) { // cekaj dok nije gotovo XNextEvent(disp, &ev); if (ev.type==MapNotify) break; } gcv.foreground=wp; gcv.background=bp; // stvori gc gc=XCreateGC(disp, win, GCForeground | GCBackground, &gcv); cout << "done." << endl; } MyDisplay::~MyDisplay() { // destruktor za graficki engine cout << "Shutting graphic subsystem.." << endl; XFreeGC(disp, gc); XDestroyWindow(disp, win); XCloseDisplay(disp); cout << "done." << endl; } struct Node_t { int x, y; // node type }; struct Poly_t { int CoordCount; // broj koordinata poligona Node_t *PolyPtr; // pokazivac na matricu sa koordinatama poligona Node_t *PointPtr; // pokazivac na matricu sa koordinatama tocke }; class MyDraw3 : public MyDisplay { Poly_t MyPolyPtr; long *a, *b, *c; // long buduci da se koordinate mnoze int x0, y0, a1, b1, c1, N0, *s; // ove vrijednosti mogu biti // cjelobrojne float x3, y3, x2, y2, t, t1, d1, d2; // ali ove ne! void MyCalcCoef(void); void MyWait(void); void MyDrawPoly(void); void MyCheckPointPoly(void); void MyPolyFill(void); void V32(void); void V31(void); public: MyDraw3(Poly_t tmpSrc); }; MyDraw3::MyDraw3(Poly_t tmpSrc) : MyPolyPtr(tmpSrc) { // konstruktor koji poziva bitne pod-dijelove MyDrawPoly(); MyCalcCoef(); MyCheckPointPoly(); XFlush(disp); MyWait(); MyPolyFill(); XFlush(disp); MyWait(); } void MyDraw3::MyDrawPoly(void) { // rutina za iscrtavanje poligona int i; for (i=0; i<=MyPolyPtr.CoordCount; i++) { XDrawLine(disp, win, gc, MyPolyPtr.PolyPtr[i].x, MyPolyPtr.PolyPtr[i].y, MyPolyPtr.PolyPtr[i+1].x, MyPolyPtr.PolyPtr[i+1].y); } } void MyDraw3::MyWait(void) { // postavi wait na keypress XSelectInput(disp, win, KeyPressMask | ExposureMask); while(1) { XNextEvent(disp, &ev); if (ev.type==KeyPress) break; } } void MyDraw3::MyCalcCoef(void) { // izracunavanje koeficijenata jednadzbi bridova int crdcnt=MyPolyPtr.CoordCount; a=new long[crdcnt]; b=new long[crdcnt]; c=new long[crdcnt]; for(int i=0; i1.) continue; if (t==1.) { // linija i brid se sijeku u zavrsnom vrhu brida, // te ako je i-ti brid i (i+1)-ti brid ispod/iznad // linije treba odbaciti sjeciste x2=MyPolyPtr.PolyPtr[i+2].x; y2=MyPolyPtr.PolyPtr[i+2].y; d1=a1*MyPolyPtr.PointPtr[0].x+b1* MyPolyPtr.PointPtr[0].y+c1; d2=a1*x2+b1*y2+c1; if ((d1>0. && d2>0.) || (d1<0. && d2<0.)) continue; s[N0++]=(int)t1; } else s[N0++]=(int)t1; } } void MyDraw3::V32(void) { // metoda V32 koja sluzi da za liniju (x1,y1) i (x2,y2) odredimo // parametar t za tocku linije (x3,y3) d1=x2-MyPolyPtr.PointPtr[0].x; d2=y2-MyPolyPtr.PointPtr[0].y; if (d1) t=(x3-MyPolyPtr.PointPtr[0].x)/d1; if (d2) t=(y3-MyPolyPtr.PointPtr[0].y)/d2; } void MyDraw3::MyPolyFill(void) { // metoda koja sluzi da punjenje konkavnog poligona int xmin, xmax, ymin, ymax, Z, i, j; xmin=xmax=MyPolyPtr.PolyPtr[0].x; ymin=ymax=MyPolyPtr.PolyPtr[0].y; int tmpP; for(i=0; ixmax) xmax=tmpP; if (tmpPymax) ymax=tmpP; if (tmpPs[i+1]) { t=s[i]; s[i]=s[i+1]; s[i+1]=(int)t; Z=1; } } } while (Z); // punjenje for (j=0; j<=N0-1; j+=2) XDrawLine(disp, win, gc, s[j], y0, s[j+1], y0); } } Poly_t MyAllInput(void) { Poly_t tmpPolyPtr; // unos broja koordinata do { cout << "Unesi broj vrhova n konveksnog poligona "; cin >> tmpPolyPtr.CoordCount; } while (tmpPolyPtr.CoordCount<3); // alociraj prostor za n vrhova tmpPolyPtr.PolyPtr=new Node_t[tmpPolyPtr.CoordCount+2]; int i; for (i=0; i> tmpPolyPtr.PolyPtr[i].x; cin >> tmpPolyPtr.PolyPtr[i].y; } // konkavni poligon! spoji krajnje tocke tmpPolyPtr.PolyPtr[i]=tmpPolyPtr.PolyPtr[0]; tmpPolyPtr.PolyPtr[i+1]=tmpPolyPtr.PolyPtr[1]; tmpPolyPtr.PointPtr=new Node_t[1]; cout << "Unesi x,y koordinate tocke V(x1,y1) "; cin >> tmpPolyPtr.PointPtr[0].x; cin >> tmpPolyPtr.PointPtr[0].y; return tmpPolyPtr; } int main(void) { MyDraw3 MyDraw3Object(MyAllInput()); return EXIT_SUCCESS; }