#include #include #include #include #include "delete.h" #include "voronoi.h" #define random( x ) ( rand() % (x) ) #define randomize() ( srand(time(NULL)) ) #define modfl modf #define fabsl fabs char *progname; SBOD *poc_sbod; SHRANA *poc_shrana=NULL; SPBOD *poc_spbod=NULL; int pocetbodu,maxx = 640, maxy = 480; void ShromazdiBody(void) { SBOD *pom_sbod; int i=0,x,y; FILE *fw; poc_sbod=NULL; randomize(); #ifdef DEBUG if ((fw=fopen("TEST.TXT","r"))==NULL) werror("Nemuzu otevrit soubor"); fscanf(fw,"%d",&pocetbodu); #endif while (i!=pocetbodu) { if ((pom_sbod=(SBOD *)malloc(sizeof(SBOD)))==NULL) werror("Neni dost pameti"); #ifndef DEBUG pom_sbod->x=(long double)( random(2*maxx/5)+2*maxx/5); pom_sbod->y=(long double)( random(2*maxy/5)+2*maxy/5); #endif #ifdef DEBUG fscanf(fw,"%d",&x); fscanf(fw,"%d",&y); pom_sbod->x=(long double)x; pom_sbod->y=(long double)y; #endif pom_sbod->dalsi=poc_sbod; pom_sbod->hrany=NULL; poc_sbod=pom_sbod; i++; } if ((pom_sbod=(SBOD *)malloc(sizeof(SBOD)))==NULL) werror("Neni dost pameti"); pom_sbod->dalsi=poc_sbod; poc_sbod=pom_sbod; #ifdef DEBUG fclose(fw); #endif } void QuickSort(SBOD *poc_sbod, int pocet) { long double stredx,stredy; SBOD *aktual_sbod,*pom_sbod,*poc2_sbod,*poc3_sbod; int i,poc1,poc2; poc2_sbod=poc_sbod; poc1=poc2=0; aktual_sbod=poc_sbod->dalsi; stredx=aktual_sbod->x; stredy=aktual_sbod->y; for (i=1;idalsi->xdalsi->x==stredx) && (aktual_sbod->dalsi->y>stredy))) { pom_sbod=poc2_sbod->dalsi; poc2_sbod=poc2_sbod->dalsi=aktual_sbod->dalsi; aktual_sbod->dalsi=aktual_sbod->dalsi->dalsi; poc2_sbod->dalsi=pom_sbod; poc1++; } else if ((stredxdalsi->x)||(aktual_sbod->dalsi->ydalsi; poc2++; } else { pom_sbod=aktual_sbod->dalsi; aktual_sbod->dalsi=aktual_sbod->dalsi->dalsi; free(pom_sbod); pocetbodu--; } } poc3_sbod=poc2_sbod->dalsi; if (poc1>1) QuickSort(poc_sbod,poc1); if (poc2>1) QuickSort(poc3_sbod,poc2); } SOBAL *Osvetli(SBOD *NovyBod) { static SOBAL *HorniObal=NULL; static SOBAL *DolniObal=NULL; SOBAL *Osvetleni,*KonecOsvetleni,*PomObal,*PomOsvetleni; Osvetleni=NULL; if ((PomObal=(SOBAL *)malloc(sizeof(SOBAL)))==NULL) werror("Nenin dost pameti"); PomObal->bod=NovyBod; PomObal->dalsi=HorniObal; HorniObal=PomObal; if ((PomObal=(SOBAL *)malloc(sizeof(SOBAL)))==NULL) werror("Nenin dost pameti"); PomObal->bod=NovyBod; PomObal->dalsi=DolniObal; DolniObal=PomObal; if (HorniObal->dalsi!=NULL) { while (HorniObal->dalsi->dalsi!=NULL) { if (((HorniObal->dalsi->bod->x-HorniObal->dalsi->dalsi->bod->x)* (HorniObal->bod->y-HorniObal->dalsi->bod->y)- (HorniObal->bod->x-HorniObal->dalsi->bod->x)* (HorniObal->dalsi->bod->y-HorniObal->dalsi->dalsi->bod->y))<=0) break; else { PomObal=HorniObal->dalsi; HorniObal->dalsi=HorniObal->dalsi->dalsi; if (Osvetleni==NULL) KonecOsvetleni=PomObal; PomObal->dalsi=Osvetleni; Osvetleni=PomObal; } } } if (DolniObal->dalsi!=NULL) { while (DolniObal->dalsi->dalsi!=NULL) { if (((DolniObal->dalsi->bod->x-DolniObal->dalsi->dalsi->bod->x)* (DolniObal->bod->y-DolniObal->dalsi->bod->y)- (DolniObal->bod->x-DolniObal->dalsi->bod->x)* (DolniObal->dalsi->bod->y-DolniObal->dalsi->dalsi->bod->y))>=0) break; else { PomObal=DolniObal->dalsi; DolniObal->dalsi=DolniObal->dalsi->dalsi; PomOsvetleni=Osvetleni; while ((PomOsvetleni!=NULL)&&(PomOsvetleni->bod!=PomObal->bod)) PomOsvetleni=PomOsvetleni->dalsi; if (PomOsvetleni==NULL) { if (Osvetleni==NULL) { Osvetleni=PomObal; KonecOsvetleni=PomObal; PomObal->dalsi=NULL; } else { KonecOsvetleni=KonecOsvetleni->dalsi=PomObal; PomObal->dalsi=NULL; } } else free(PomObal); } } if (Osvetleni==NULL) { if ((PomObal=(SOBAL *)malloc(sizeof(SOBAL)))==NULL) werror("Neni dost pameti"); Osvetleni=PomObal; PomObal->bod=DolniObal->dalsi->bod; PomObal->dalsi=NULL; KonecOsvetleni=PomObal; } else if (KonecOsvetleni->bod!=DolniObal->dalsi->bod) { if ((PomObal=(SOBAL *)malloc(sizeof(SOBAL)))==NULL) werror("Neni dost pameti"); PomObal->bod=DolniObal->dalsi->bod; PomObal->dalsi=NULL; KonecOsvetleni=KonecOsvetleni->dalsi=PomObal; } } if (HorniObal->dalsi!=NULL) { if (Osvetleni->bod!=HorniObal->dalsi->bod) { if ((PomObal=(SOBAL *)malloc(sizeof(SOBAL)))==NULL) werror("Neni dost pameti"); PomObal->bod=HorniObal->dalsi->bod; PomObal->dalsi=Osvetleni; if (Osvetleni==NULL) KonecOsvetleni=PomObal; Osvetleni=PomObal; } } return(Osvetleni); } long double Zaokrouhli(long double hodnota) { long double vysledek,ipart; if (hodnota>0.0) { ipart=modfl(10000000*hodnota,&vysledek); if (ipart>0.5) vysledek++; vysledek/=10000000; } if (hodnota<0.0) { ipart=modfl(10000000*fabsl(hodnota),&vysledek); if (ipart>0.5) vysledek++; vysledek=-vysledek/10000000; } if (hodnota==0.0) vysledek=0.0; return(vysledek); } SHRANA *VytvorHranu(SBOD *bod1,SBOD *bod2) { SHRANA *PomHrana; SHRANY *PointerHrany; if ((PomHrana=(SHRANA *)malloc(sizeof(SHRANA)))==NULL) werror("Neni dost pameti"); PomHrana->bod1=bod1; PomHrana->bod2=bod2; PomHrana->a=Zaokrouhli(bod1->x-bod2->x); PomHrana->b=Zaokrouhli(bod1->y-bod2->y); PomHrana->c=Zaokrouhli(((bod2->x-bod1->x)*(bod2->x+bod1->x)+ (bod2->y-bod1->y)*(bod2->y+bod1->y))/2); PomHrana->prirustek=0; PomHrana->pbod1=PomHrana->pbod2=NULL; if ((PointerHrany=(SHRANY *)malloc(sizeof(SHRANY)))==NULL) werror("Neni dost pameti"); PointerHrany->hrana=PomHrana; PointerHrany->dalsi=bod1->hrany; bod1->hrany=PointerHrany; if ((PointerHrany=(SHRANY *)malloc(sizeof(SHRANY)))==NULL) werror("Neni dost pameti"); PointerHrany->hrana=PomHrana; PointerHrany->dalsi=bod2->hrany; bod2->hrany=PointerHrany; PomHrana->dalsi=poc_shrana; poc_shrana=PomHrana; return(PomHrana); } int PrunikHran(long double *x,long double *y,SHRANA *hrana1,SHRANA *hrana2) { long double lom,rozdil12,rozdil1,rozdil2; SPBOD *Bod1,*Bod2; if ((lom=hrana1->a*hrana2->b-hrana1->b*hrana2->a)==0.0) return(2); /*mijeji se*/ *x=Zaokrouhli((hrana1->b*hrana2->c-hrana1->c*hrana2->b)/lom); *y=Zaokrouhli((hrana1->c*hrana2->a-hrana1->a*hrana2->c)/lom); Bod1=hrana1->pbod1; Bod2=hrana1->pbod2; if (Bod2==NULL) { if (Bod1==NULL) return(1); else if (*y-Bod1->y>0.0001) return(hrana1->prirustek); else if (*y-Bod1->y<-0.0001) return(1^hrana1->prirustek); else if (*x-Bod1->x>0.0001) return(hrana1->prirustek); else if (*x-Bod1->x<-0.0001) return(1^hrana1->prirustek); else return(3); } else { rozdil12=fabsl(Bod1->x-Bod2->x)+fabsl(Bod1->y-Bod2->y); rozdil1=fabsl(Bod1->x-*x)+fabsl(Bod1->y-*y); rozdil2=fabsl(Bod2->x-*x)+fabsl(Bod2->y-*y); if (rozdil1>rozdil12) return(0); else if (rozdil2>rozdil12) return(0); else if (rozdil1==0.0) return(3); else if (rozdil2==0.0) return(4); else return(1); } } SHRANA *NajdiHranu(SBOD *Bod1,SBOD *Bod2) { SHRANY *Hrany; Hrany=Bod1->hrany; while ((Hrany!=NULL)&&(Hrany->hrana->bod1!=Bod2)&&(Hrany->hrana->bod2!=Bod2)) Hrany=Hrany->dalsi; if (Hrany==NULL) werror("Takova hrana neexistuje"); return(Hrany->hrana); } SHRANA *NajdiHranu2(SPBOD *Uzel,SBOD *Bod,SHRANA *RusenaHrana) { SHRANY *Hrany; /* long double x,y; */ Hrany=Uzel->hrany; znovu: while ((Hrany!=NULL)&&(Hrany->hrana->bod1!=Bod)&&(Hrany->hrana->bod2!=Bod)) Hrany=Hrany->dalsi; if (Hrany==NULL) werror("Takova hrana neexistuje"); /* else if (Hrany->hrana->bod1==Bod) { x=Hrany->hrana->bod2->x; y=Hrany->hrana->bod2->y; } else { // pak Hrany->hrana->bod2==Bod x=Hrany->hrana->bod1->x; y=Hrany->hrana->bod1->y; } */ if (Hrany->hrana==RusenaHrana) { Hrany=Hrany->dalsi; goto znovu; } return(Hrany->hrana); } SPBOD *VytvorPBod(long double x,long double y,SHRANA *Hrana1,SHRANA *Hrana2) { SPBOD *Uzel; SHRANY *Hrany1,*Hrany2; if ((Uzel=(SPBOD *)malloc(sizeof(SPBOD)))==NULL) werror("Neni dost pameti"); Uzel->x=x; Uzel->y=y; Uzel->dalsi=poc_spbod; poc_spbod=Uzel; if ((Hrany1=(SHRANY *)malloc(sizeof(SHRANY)))==NULL) werror("Neni dost pameti"); if ((Hrany2=(SHRANY *)malloc(sizeof(SHRANY)))==NULL) werror("Neni dost pameti"); Hrany2->dalsi=NULL; Hrany1->hrana=Hrana1; Hrany2->hrana=Hrana2; Hrany1->dalsi=Hrany2; Uzel->hrany=Hrany1; return(Uzel); } void ZasnubHrany(SHRANA *Hrana1,SHRANA *Hrana2) { if (Hrana1->bod1==Hrana2->bod2) { Hrana2->bod2=Hrana2->bod1; Hrana2->bod1=Hrana1->bod1; } else if (Hrana1->bod2==Hrana2->bod1) { Hrana1->bod2=Hrana1->bod1; Hrana1->bod1=Hrana2->bod1; } else if (Hrana1->bod2==Hrana2->bod2) { Hrana1->bod2=Hrana1->bod1; Hrana1->bod1=Hrana2->bod2; Hrana2->bod2=Hrana2->bod1; Hrana2->bod1=Hrana1->bod1; } if ((Hrana1->pbod1==Hrana2->pbod2)&&(Hrana1->pbod1!=NULL)) { Hrana2->pbod2=Hrana2->pbod1; Hrana2->pbod1=Hrana1->pbod1; } else if ((Hrana1->pbod2==Hrana2->pbod1)&&(Hrana1->pbod2!=NULL)) { Hrana1->pbod2=Hrana1->pbod1; Hrana1->pbod1=Hrana2->pbod1; } else if ((Hrana1->pbod2==Hrana2->pbod2)&&(Hrana1->pbod2!=NULL)) { Hrana1->pbod2=Hrana1->pbod1; Hrana1->pbod1=Hrana2->pbod2; Hrana2->pbod2=Hrana2->pbod1; Hrana2->pbod1=Hrana1->pbod1; } } SPBOD *Kolize(SHRANA *StaraHrana,SHRANA *KolizHrana) { long double x,y; SPBOD *Uzel,*Uzel2; SHRANY *Hrany,*PomHrany; SBOD *Bod,*PomBod; SBOD *MezniBod; SBOD *NovyBod; SHRANA *RusenaHrana,*StaraHrana2; switch (PrunikHran(&x,&y,StaraHrana,KolizHrana)) { case 1:Uzel=VytvorPBod(x,y,StaraHrana,KolizHrana); if (KolizHrana->pbod1==NULL) KolizHrana->pbod1=Uzel; else KolizHrana->pbod2=Uzel; if (StaraHrana->pbod1==NULL) { StaraHrana->pbod1=Uzel; ZasnubHrany(StaraHrana,KolizHrana); if ((StaraHrana->bod1->xbod2->x)|| ((StaraHrana->bod1->x==StaraHrana->bod2->x)&& (StaraHrana->bod1->y>StaraHrana->bod2->y))) { if (VektorovySoucin(StaraHrana->bod1->x,StaraHrana->bod1->y, StaraHrana->bod2->x,StaraHrana->bod2->y, KolizHrana->bod2->x,KolizHrana->bod2->y)<0.0) StaraHrana->prirustek=1; else StaraHrana->prirustek=0; } else { if (VektorovySoucin(StaraHrana->bod2->x,StaraHrana->bod2->y, StaraHrana->bod1->x,StaraHrana->bod1->y, KolizHrana->bod2->x,KolizHrana->bod2->y)<0.0) StaraHrana->prirustek=1; else StaraHrana->prirustek=0; } } else StaraHrana->pbod2=Uzel; return(Uzel); case 0:Uzel=StaraHrana->pbod1;RusenaHrana=StaraHrana; Hrany=Uzel->hrany; while (Hrany!=NULL) { if (Hrany->hrana->pbod1==Uzel) { Hrany->hrana->pbod1=Hrany->hrana->pbod2; Hrany->hrana->pbod2=NULL; if ((Hrany->hrana->pbod1!=NULL)&&((Uzel->y>Hrany->hrana->pbod1->y)|| ((Uzel->y==Hrany->hrana->pbod1->y)&&(Uzel->x>Hrany->hrana->pbod1->x)))) Hrany->hrana->prirustek=1; else Hrany->hrana->prirustek=0; } else if (Hrany->hrana->pbod2==Uzel) { Hrany->hrana->pbod2=NULL; if ((Uzel->y>Hrany->hrana->pbod1->y)|| ((Uzel->y==Hrany->hrana->pbod1->y)&&(Uzel->x>Hrany->hrana->pbod1->x))) Hrany->hrana->prirustek=1; else Hrany->hrana->prirustek=0; } Hrany=Hrany->dalsi; } ZasnubHrany(StaraHrana,KolizHrana); Bod=StaraHrana->bod1; MezniBod=StaraHrana->bod2; NovyBod=KolizHrana->bod2; StaraHrana2=NajdiHranu2(Uzel,Bod,RusenaHrana); ZasnubHrany(StaraHrana,StaraHrana2); PomBod=StaraHrana2->bod2; StaraHrana=StaraHrana2; while (Bod!=MezniBod) { Bod=PomBod; StaraHrana2=NajdiHranu2(Uzel,Bod,RusenaHrana); if (StaraHrana!=StaraHrana2) ZasnubHrany(StaraHrana,StaraHrana2); PomBod=StaraHrana2->bod2; Uzel2=Kolize(StaraHrana,KolizHrana); if (Bod!=MezniBod) { StaraHrana=StaraHrana2; /* if (KolizHrana->pbod1==NULL) KolizHrana->pbod1=Uzel2; else KolizHrana->pbod2=Uzel2; */ KolizHrana=VytvorHranu(NovyBod,Bod); KolizHrana->pbod1=Uzel2; KolizHrana->prirustek=0; if ((PomHrany=(SHRANY *)malloc(sizeof(SHRANY)))==NULL) werror("Neni dost pameti"); PomHrany->dalsi=Uzel2->hrany; Uzel2->hrany=PomHrany; PomHrany->hrana=KolizHrana; } } ZrusHranu(RusenaHrana); ZrusPBod(Uzel); return(Uzel2); case 3:Uzel=StaraHrana->pbod1; if (KolizHrana->pbod1==NULL) KolizHrana->pbod1=Uzel; else KolizHrana->pbod2=Uzel; KolizHrana->prirustek=1; ZrusHranu(StaraHrana); if ((Hrany=(SHRANY *)malloc(sizeof(SHRANY)))==NULL) werror("Neni dost pameti"); Hrany->dalsi=Uzel->hrany; Uzel->hrany=Hrany; Hrany->hrana=KolizHrana; return(Uzel); case 2:werror("Jaktoze jsou to rovnobezky?"); case 4:werror("Tento pripad by nemel nastat"); default:werror("Chybna hodnota z PrunikHran"); } werror("Sem se to nemuze dostat"); return(Uzel); } void Voronoi(void) { SBOD *Bod; SPBOD *Uzel; SOBAL *Osvetleni,*RuseneOsvetleni; SHRANA *StaraHrana,*KolizHrana; SHRANY *PomHrany; int prvni; Bod=poc_sbod->dalsi; while (Bod!=NULL) { Osvetleni=Osvetli(Bod); Uzel=NULL; prvni=1; while (Osvetleni!=NULL) { RuseneOsvetleni=Osvetleni; KolizHrana=VytvorHranu(Osvetleni->bod,Bod); KolizHrana->pbod1=Uzel; if (Uzel!=NULL) { if ((PomHrany=(SHRANY *)malloc(sizeof(SHRANY)))==NULL) werror("Neni dost pameti"); PomHrany->dalsi=Uzel->hrany; Uzel->hrany=PomHrany; PomHrany->hrana=KolizHrana; } if (prvni) { KolizHrana->prirustek=1; prvni=0; } if (Osvetleni->dalsi!=NULL) { StaraHrana=NajdiHranu(Osvetleni->bod,Osvetleni->dalsi->bod); Uzel=Kolize(StaraHrana,KolizHrana); } Osvetleni=Osvetleni->dalsi; free(RuseneOsvetleni); } Bod=Bod->dalsi; } } void PridejBod(int d,long double x,long double y,BOD *Bod1,BOD *Bod2) { if ((d==1)||(d==3)||(d==4)) { if (Bod1->x<0.0) { Bod1->x=(int)x; Bod1->y=(int)y; } else if (((Bod1->x!=x)||(Bod1->y!=y))&&(Bod2->x<0)) { Bod2->x=(int)x; Bod2->y=(int)y; } } } int JeUvnitr(SPBOD *Uzel) { if (Uzel==NULL) return(0); if ((0.0<=Uzel->x)&&(Uzel->x<=(long double)maxx)&&(0.0<=Uzel->y)&&(Uzel->y<=(long double)maxy)) return(1); else return(0); } void Tiskni(void) { long double x,y; SHRANA *Hrana,HrXje0,HrXjeMAXX,HrYje0,HrYjeMAXY; BOD Bod1,Bod2; SBOD *Bod; int d; Hrana=poc_shrana; HrXje0.a=1.0; HrXje0.b=0.0; HrXje0.c=0.0; HrXjeMAXX.a=1.0; HrXjeMAXX.b=0.0; HrXjeMAXX.c=-(long double)maxx; HrYje0.a=0.0; HrYje0.b=1.0; HrYje0.c=0.0; HrYjeMAXY.a=0.0; HrYjeMAXY.b=1.0; HrYjeMAXY.c=-(long double)maxy; Bod=poc_sbod->dalsi; while (Bod!=NULL) { printf( "%d, %d, %d, %d, %d\n", 0, (int)Bod->x, (int)Bod->y, 0, 0 ); Bod=Bod->dalsi; } while (Hrana!=NULL) { Bod1.x=-1.0; Bod2.x=-1.0; d=PrunikHran(&x,&y,Hrana,&HrXje0); if ((0.0<=y)&&(y<=(long double)maxy)) PridejBod(d,x,y,&Bod1,&Bod2); d=PrunikHran(&x,&y,Hrana,&HrXjeMAXX); if ((0.0<=y)&&(y<=(long double)maxy)) PridejBod(d,x,y,&Bod1,&Bod2); d=PrunikHran(&x,&y,Hrana,&HrYje0); if ((0.0<=x)&&(x<=(long double)maxx)) PridejBod(d,x,y,&Bod1,&Bod2); d=PrunikHran(&x,&y,Hrana,&HrYjeMAXY); if ((0.0<=x)&&(x<=(long double)maxx)) PridejBod(d,x,y,&Bod1,&Bod2); if (JeUvnitr(Hrana->pbod1)) PridejBod(1,Hrana->pbod1->x,Hrana->pbod1->y,&Bod1,&Bod2); if (JeUvnitr(Hrana->pbod2)) PridejBod(1,Hrana->pbod2->x,Hrana->pbod2->y,&Bod1,&Bod2); printf( "%d, %d, %d, %d, %d\n", 1, (int)Bod1.x,(int)Bod1.y,(int)Bod2.x,(int)Bod2.y ); Hrana=Hrana->dalsi; } } int main(int argc,char **argv) { char *name; /*SBOD *Bod;*/ SPBOD *Mbod; int gdriver = 0, gmode, errorcode; if (argc>0) { progname=argv[0]; } else { progname="VORONOI"; } pocetbodu=POCETBODU; if (argc>1) sscanf(argv[1],"%d",&pocetbodu); ShromazdiBody(); QuickSort(poc_sbod,pocetbodu); /* Bod=poc_sbod->dalsi; while(Bod!=NULL) { printf("%d,%d\n",(int)Bod->x,(int)Bod->y); Bod=Bod->dalsi; } */ Voronoi(); /* Bod=poc_sbod->dalsi; while(Bod!=NULL) { printf("%d,%d\n",(int)Bod->x,(int)Bod->y); Bod=Bod->dalsi; } */ Tiskni(); return(0); }