题目大意:有一个正N边形,然后给出两个点,求出剩余的点的坐标。
分析:向量旋转可以求出坐标,顺时针旋转时候,x = x'*cos(a) + y'*sin(a), y=-x'*sin(a) + y'*cos(a), 逆时针时候 x = x'*cos(a)-y'*sin(a), y=x'*sin(a)+y'*cos(a)。题目中先求出来圆心,然后再求剩余的点,不过求圆心的时候一定注意判断一下两点的角度是否大于PI。
代码如下:
==========================================================================================================
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; const int MAXN = 1007; const double PI = acos(-1.0); const double EPS = 1e-7; struct point { double x, y; point(double x=0, double y=0):x(x),y(y){} point operator - (const point &tmp)const{ return point(x-tmp.x, y-tmp.y); } double operator *(const point &tmp)const{ return x*tmp.x+y*tmp.y; } }; double Dis(point a, point b) { return sqrt((a-b)*(a-b)); } struct segment { point s, e; segment(point s=0, point e=0):s(s),e(e){} point Turn(double len, double a) {///线段绕点s旋转a角度后长len的坐标,顺时针 point t = e-s, ans; double len1 = Dis(s, e); /// printf("sin(a)=%lf, cos(a)=%lf ", sin(a), cos(a)); ans.x = s.x + (t.y*sin(a)+t.x*cos(a))*len/len1; ans.y = s.y + (-t.x*sin(a)+t.y*cos(a))*len/len1; return ans; } }; int main() { point p[MAXN]; int N, A, B; scanf("%d%d%d", &N, &A, &B); A-= 1, B-=1; scanf("%lf%lf%lf%lf", &p[A].x, &p[A].y, &p[B].x, &p[B].y); if(A > B)swap(A, B); double a, b, R; segment L; if(B-A >= N/2) {///夹角大于PI a = PI * 2 / N; b = PI/2 - a * (N-(B-A)) / 2; L.s = p[B], L.e = p[A]; } else { a = PI * 2 / N; b = PI/2 - a * (B-A) / 2; L.s = p[A], L.e = p[B]; } R = Dis(L.s, L.e) / 2 / cos(b); point heart = L.Turn(R, b); L.s = heart; for(int i=0; i<N; i++) { L.e = p[(A+i)%N]; p[(A+i+1)%N] = L.Turn(R, a); } for(int i=0; i<N; i++) { if(fabs(p[i].x) <= EPS)p[i].x = EPS; if(fabs(p[i].y) <= EPS)p[i].y = EPS; printf("%.6f %.6f ", p[i].x+1e-10, p[i].y+1e-10); } return 0; }