All pastes #537121 Raw Edit

Untitled

public text v1 · immutable
·published 2007-06-04 17:03 UTC
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);
	}
}