题目链接:http://poj.org/problem?id=1931
判断两个多边形是否相似
多边形相似充要条件:多边形A的任何两点之间长度,与多边形B对应的两个点
长度比值都相等注意一下顺时针和逆时针,还有数值的范围*/
#include <math.h>
#include <stdio.h>
#define eps 1e-6
#define sqr(x) ((x) * (x))
#define same(a, b) (fabs((a) - (b)) < eps)
#define dis2(a, b) (sqrt(sqr(a.x - b.x) + sqr(a.y - b.y)))
struct point
{
double x, y;
point operator-(point &b)
{
point c;
c.x = x - b.x;
c.y = y - b.y;
return c;
}
};
double dot(point a, point b)
{
return a.x * b.x + a.y * b.y;
}
double cross(point a, point b)
{
return a.x * b.y - a.y * b.x;
}
double get_anlge(point p1, point p2, point p3)
{
//不需要求反余弦,点击相当,反余弦相等,避免使用反三角函数
return dot(p1 - p2, p3 - p2) / dis2(p1, p2) / dis2(p2, p3);
}
int get_dir(point p1, point p2, point p3)
{
//根据三点得到转向
double t1 = cross(p2 - p1, p3 - p2);
if(fabs(t1) < eps) return 1;
if(t1 < 0) return 2;
else return 3;
}
int slove(double ang1[], double ang2[], double len1[], double len2[], int dir1[], int dir2[], int n)
{
/*由于题目已经告诉了对应点的匹配顺序,所以只需要从
0,开始匹配,如果没有告诉对应的匹配顺序,就还有枚举
匹配对应边*/
int s, t, k;
s = 0;
t = 0;
for(k = 0; k < n; k++)
{
if(!same(ang1[s], ang2[t]) || !same(len1[s], len2[t]) || dir1[s] != dir2[t]) break;
s++;
t++;
s %= n;
t %= n;
}
if(k == n) return 1;
return 0;
}
double polygonArea(point p[], int n)
{
//已知多边形各顶点的坐标,求其面积
double area = 0.0;
for(int i = 1; i <= n; i++)
area += (p[i - 1].x * p[i % n].y - p[i % n].x * p[i - 1].y);
return area;
}
int main()
{
int n, similar;
point p1[20], p2[20];
double max1, max2;
double ang1[20], ang2[20], len1[20], len2[20];
int dir1[20], dir2[20];
while(scanf("%d", &n) && n)
{
for(int i = 0; i < n; i++)
{
scanf("%lf%lf", &p1[i].x, &p1[i].y);
}
for(int i = 0; i < n; i++)
{
scanf("%lf%lf", &p2[i].x, &p2[i].y);
}
ang1[0] = get_anlge(p1[n - 1], p1[0], p1[1]);
ang2[0] = get_anlge(p2[n - 1], p2[0], p2[1]);
dir1[0] = get_dir(p1[n - 1], p1[0], p1[1]);
dir2[0] = get_dir(p2[n - 1], p2[0], p2[1]);
for(int i = 1; i < n; i++)
{
ang1[i] = get_anlge(p1[i - 1], p1[i], p1[(i + 1) % n]);
ang2[i] = get_anlge(p2[i - 1], p2[i], p2[(i + 1) % n]);
dir1[i] = get_dir(p1[i - 1], p1[i], p1[(i + 1) % n]);
dir2[i] = get_dir(p2[i - 1], p2[i], p2[(i + 1) % n]);
}
max1 = -1, max2 = -1;
for(int i = 0; i < n; i++)
{
len1[i] = dis2(p1[i], p1[(i + 1) % n]);
if(len1[i] > max1) max1 = len1[i];
len2[i] = dis2(p2[i], p2[(i + 1) % n]);
if(len2[i] > max2) max2 = len2[i];
}
for(int i = 0; i < n; i++)
{
len1[i] /= max1;
len2[i] /= max2;
}
if(slove(ang1, ang2, len1, len2, dir1, dir2, n)) printf("similar\n");
else printf("dissimilar\n");
}
return 0;
}