#include #include #include #define precision 0.00000001 #define PI 3.14159265358979323846 typedef long double ld; typedef struct { ld mod; //odleglosc od poczatku ukladu wspolrzednych ld x; ld y; } punkt; typedef struct { ld kat; int active; } linia; inline ld katOX (ld, ld); int sym_cmp (const void * c, const void * d) { linia * a = *(linia * const *)c; linia * b = *(linia * const *)d; //posortuj katow if (fabs(a->kat - b->kat) <= precision) {//rozszerzony znak rownosci return 0; } else if (a->kat > b->kat){ return 1; } else { return -1; } } int compare (const void * c, const void * d) { ld k1, k2; punkt * a = *(punkt * const *)c; punkt * b = *(punkt * const *)d; //if ( fabs(((punkty*)a)->mod - ((punkty*)b)->mod) <= precision) { // posortuj przeciwnie do wskazowek zegara if ( fabs(a->mod - b->mod) <= precision) { // posortuj przeciwnie do wskazowek zegara k1 = katOX(a->x, a->y); k2 = katOX(b->x, b->y); if (k1 > k2) return 1; else if (k1 < k2) return -1; else return 0; } else if (a->mod > b->mod) { return 1; } else if (a->mod < b->mod) { return -1; } else { return 0; } } int main() { #ifndef ONLINE_JUDGE freopen("in2","r",stdin); //freopen("out.txt","w",stdout); #endif //punkty punkty[ilosc_punktow]; //ld katy[ilosc_punktow]; // -1 // katy miedzy sasiednimi punktami //ld katy2[ilosc_punktow]; //linia symetrie[ilosc_punktow]; ld x, y; //wspolrzedne srodka int n, i_punktow, i, i2, n3; int numer_zbioru=0, sym=0; int match, tmp_n; scanf("%d", &i_punktow); getchar(); punkt ** punkty = (punkt**)malloc(sizeof(punkt*)*i_punktow); for (n=0; n < i_punktow; n++) punkty[n] = (punkt*)malloc(sizeof(punkt)); ld * katy = (ld*)malloc(sizeof(ld)*i_punktow); linia ** symetrie = (linia**)malloc(sizeof(linia*)*i_punktow); for (n=0; n < i_punktow; n++) symetrie[n] = (linia*)malloc(sizeof(linia)); x = 0; y = 0; for (n=0; n < i_punktow; n++) { //wczyt scanf("%Lf %Lf", &punkty[n]->x, &punkty[n]->y); getchar(); //printf("%Lf %Lf\n", punkty[n]->x, punkty[n]->y); x += punkty[n]->x; y += punkty[n]->y; } //return 0; x /= i_punktow; //ciezar srodka y /= i_punktow; for (n=0; n < i_punktow; n++) { //srodek punkty[n]->x-= x; punkty[n]->y-= y; } for (n=0; n < i_punktow; n++) { //odelglosci od srodka ciezaru punkty[n]->mod = sqrt(punkty[n]->x*punkty[n]->x+punkty[n]->y*punkty[n]->y); } printf("%.10Lf %.10Lf\n", x, y); qsort(punkty, i_punktow, sizeof(punkty[0]), compare); //for (n=0; n < i_punktow; n++) { // printf("%.10Lf %.10Lf %.10Lf\n", punkty[n]->mod, punkty[n]->x, punkty[n]->y); //} //return 0; i=0; while (punkty[i]->mod <= precision) i++; i2=0; while (i2 < i_punktow) { //dopuki sa punkty i2=i; while (i2 < i_punktow) if (punkty[i2]->mod-punkty[i]->mod <= precision) i2++; else break; for (n=0; n < i2-i; n++) { // S if (n+1 != i2-i) { katy[n] = katOX(punkty[n+i+1]->x, punkty[n+i+1]->y) - katOX(punkty[n+i]->x, punkty[n+i]->y); // spadek precyzji //katy[n+i2-i] = katy[n]; //katy2[i2-i-1-n] = katy[n]; } else { katy[n] = 2*PI - (katOX(punkty[n+i]->x, punkty[n+i]->y) - katOX(punkty[i]->x, punkty[i]->y)); //katy[n+i2-i] = katy[n]; //katy2[i2-i-1-n] = katy[n]; } } for (n=0; n < i2-i; n++) { if ( fabs(katy[n] - katy[i2-i-1]) <= precision) { //precyzja 10^9 n3=n; tmp_n=0; match=0; while(tmp_n < i2-i) { // mechanizm dopasowywania if (fabs(katy[n3%(i2-i)] - katy[(i2-i-tmp_n-1)%(i2-i)]) <= precision) { //precyzja 10^8 //if (fabs(katy[n3] - katy2[tmp_n]) <= precision) { match++; n3++; tmp_n++; } else { match = 0; break; } } if (match > 0) { if (n3 == 1) { x = katOX(punkty[i]->x, punkty[i]->y); } else if (n3%2==0) { x = katOX(punkty[i+n3/2]->x, punkty[i+n3/2]->y); } else { x = katy[n3/2]/2+ katOX(punkty[i+n3/2]->x, punkty[i+n3/2]->y); } while(x > PI) x-=PI; if (x <= precision) x = PI; if (numer_zbioru == 0) { symetrie[sym]->kat = x; symetrie[sym]->active = 0; sym++; } else { for (n3=0; n3 < sym; n3++) { //sym ilosc symetrii if (fabs(symetrie[n3]->kat - x) <= precision) // 2 takie same osie ?? symetrie[n3]->active++; } } } } } i = i2; numer_zbioru++; } qsort(symetrie, sym , sizeof(symetrie[0]), sym_cmp); // sortowanie po katach for (n = 0;n < sym; n++) { if (symetrie[n]->active == numer_zbioru-1) printf("%.10Lf\n", symetrie[n]->kat); } return 0; } inline ld katOX (ld x, ld y) { if (x == 0) { if (y >= 0) return (PI/2); //prawa granica pi/2 if (y < 0) return (3*PI/2); //lewa granica -pi/2 // 270' //return PI/2; } if (x > 0) { if (y < 0) return (atan(y/x)+2*PI); else return (atan(y/x)); } else { return (atan(y/x)+PI); } }