Archipelago - SGU 120(计算几何向量旋转)

题目大意:有一个正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 = ;
const double PI = acos(-1.0);
const double EPS = 1e-; struct point
{
double x, y;
point(double x=, double y=):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=, point e=):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\n", 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-= , B-=;
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/)
{///夹角大于PI
a = PI * / N;
b = PI/ - a * (N-(B-A)) / ;
L.s = p[B], L.e = p[A];
}
else
{
a = PI * / N;
b = PI/ - a * (B-A) / ;
L.s = p[A], L.e = p[B];
} R = Dis(L.s, L.e) / / cos(b);
point heart = L.Turn(R, b); L.s = heart; for(int i=; i<N; i++)
{
L.e = p[(A+i)%N];
p[(A+i+)%N] = L.Turn(R, a);
} for(int i=; 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\n", p[i].x+1e-, p[i].y+1e-);
} return ;
}
上一篇:Minitab中相关系数R-Sq和修正R-Sq(adj)的意思,计算公式和区别[转载]


下一篇:ubuntu16.04安装skype