/**************************************************************** **************************************************************** Autor: Srdjan Vukmirovic e-mail: vsrdjan@matf.bg.ac.yu Datum: 4.11.2007. Verzija: vrlo radna Ovo je heder koji se u kursu Geometrija na Matematickom Fakultetu, u Beogradu. Glavni deo je funkcija nacrtaj(ime_fajla, string_fmt, objekti za crtanje...) Ta funkcija objekte tipa Tacka, Prava, Duz i Krug (definisane ispod) upisuje u fajl (ime_fajla). Fajl je tipa .jvx u XMLu. Otvara se besplatnim softverom JavaView (www.javaview.de). Redosled objekata mora da odgovara stringu za formatiranje (string_fmt). Recimo ako je string_fmt = "%d%d%t%k%p%p" to znaci da objekti za crtanje moraju redom biti tipova: Duz, Duz, Tacka, Krug, Prava, Prava. Ako se to pravilo ne postuje rezultati su nepredvidljivi (za sada:) *******************************************************************/ #include #include #include #include /* Definicije struktura */ typedef struct { float x; float y; } Tacka; typedef struct { Tacka start; Tacka pravac; } Prava; typedef struct { Tacka centar; float r; } Krug; typedef struct { Tacka start; Tacka end; } Duz; int nacrtaj(char *fname, char *fmt, ...) { const float pi = 3.141592; const eps = 0.000001; char *p; int i; int err =0; int imapravih =0; va_list ap; /* pokazivac na tekuci argument */ Tacka tval; Krug kval; Duz dval; Prava pval; /* Promenljive za odredjivanje granica crteza. Potrebne su zbog crtanja pravih */ float maxy = -FLT_MAX; float miny = FLT_MAX; float minx = FLT_MAX; float maxx = -FLT_MAX; float p1x, p1y, p2x, p2y; FILE *fp = fopen(fname, "w"); fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "Zadatak iz Geometrije\n"); fprintf(fp, "\n"); va_start(ap, fmt); for (p=fmt; *p; p++){ if (*p != '%') { err = 1; break; } switch (*++p){ case 't': /* argument je tacka */ tval = va_arg(ap, Tacka); if (tval.x < minx) minx = tval.x; if (tval.x > maxx) maxx = tval.x; if (tval.y < miny) miny = tval.y; if (tval.y > maxy) maxy = tval.y; fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "

%f %f

\n", tval.x, tval.y); fprintf(fp, "
\n"); fprintf(fp, "
\n"); fprintf(fp, "
\n"); break; case 'k': /* argument je krug */ kval = va_arg(ap, Krug); if (kval.centar.x - kval.r < minx) minx = kval.centar.x - kval.r; if (kval.centar.x + kval.r > maxx) maxx = kval.centar.x + kval.r; if (kval.centar.y - kval.r < miny) miny = kval.centar.y - kval.r; if (kval.centar.y + kval.r > maxy) maxy = kval.centar.y + kval.r; fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "\n"); /* krug se aproksimira linijama */ for(i=0; i<=40; i++){ float x0 = kval.centar.x; float y0 = kval.centar.y; float r = kval.r; fprintf(fp, "

%f %f

\n", x0 + r * cos ((pi/20) *i), y0 + r * sin ((pi/20) *i)); } fprintf(fp, "
\n"); fprintf(fp, "
\n"); fprintf(fp, "\n"); fprintf(fp, "\n"); for(i=0; i<40; i++){ fprintf(fp, "%i %i", i, i+1); } fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "
\n"); break; case 'd': /* argument je duz */ dval = va_arg(ap, Duz); if (dval.start.x < minx) minx = dval.start.x; if (dval.start.x > maxx) maxx = dval.start.x; if (dval.end.x < minx) minx = dval.end.x; if (dval.end.x > maxx) maxx = dval.end.x; if (dval.start.y < miny) miny = dval.start.y; if (dval.start.y > maxy) maxy = dval.start.y; if (dval.end.y < miny) miny = dval.end.y; if (dval.end.y > maxy) maxy = dval.end.y; fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "

%f %f

\n", dval.start.x, dval.start.y); fprintf(fp, "

%f %f

\n", dval.end.x, dval.end.y); fprintf(fp, "
\n"); fprintf(fp, "
\n"); fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "0 1"); fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "
\n"); break; case 'p': /* argument je prava. Ona se crta kodom koji sledi ispod */ imapravih = 1; pval = va_arg(ap, Prava); if (pval.start.x < minx) minx = pval.start.x; if (pval.start.x > maxx) maxx = pval.start.x; if (pval.start.y < miny) miny = pval.start.y; if (pval.start.y > maxy) maxy = pval.start.y; break; default: err = 1; break; } va_end(ap); } if (imapravih){ /* Ako ima pravih one se sada upisuju u fajl imajuci u vidu granice crteza */ va_start(ap, fmt); /* koliko prave strce van konacnih objekata */ maxx = maxx + 0.8 * (maxx - minx); minx = minx - 0.8 * (maxx - minx); maxy = maxy + 0.8 * (maxy - miny); miny = miny - 0.8 * (maxy - miny); for (p=fmt; *p; p++){ if (*p != '%') { err = 1; break; } /* lose reseno - popraviti */ switch (*++p){ case 't': tval = va_arg(ap, Tacka); break; case 'k': kval = va_arg(ap, Krug); break; case 'd': dval = va_arg(ap, Duz); break; case 'p': pval = va_arg(ap, Prava); if (abs(pval.pravac.x) < eps) {p1x = pval.start.x; p1y = maxy; p2x = pval.start.x; p2y = miny;} else if (abs(pval.pravac.y) < eps) {p1x = minx; p1y = pval.start.y ; p2x = maxx; p2y = pval.start.y;} else{ /* prava je nagnuta nalevo */ if (pval.pravac.x * pval.pravac.y <0){ p1x = minx; p1y = pval.start.y + ((minx -pval.start.x)/pval.pravac.x)*pval.pravac.y; if(p1y >maxy){ p1y = maxy; p1x = pval.start.x + ((maxy -pval.start.y)/pval.pravac.y)*pval.pravac.x; } p2x = maxx; p2y = pval.start.y + ((maxx -pval.start.x)/pval.pravac.x)*pval.pravac.y; if(p2y maxy){ p2y = maxy; p2x = pval.start.x + ((maxy -pval.start.y)/pval.pravac.y)*pval.pravac.x; } } } fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "

%f %f

\n", p1x, p1y); fprintf(fp, "

%f %f

\n", p2x, p2y); fprintf(fp, "
\n"); fprintf(fp, "
\n"); fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "0 1"); fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "
\n"); fprintf(fp, "
"); fprintf(fp, "
"); default: break; } /* switch */ } /* for */ va_end(ap); } /* if imapravih */ fclose(fp); return err; }