rendered paste body#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#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) //<to do> 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);
}
}