Problem 1007 Biometrics FOJ

来源:http://acm.fzu.edu.cn/problem.php?pid=1007

Problem Description
Recently, the term Biometrics been used to refer to the emerging field of technology devoted to identification of individuals using biological traits, such as those based on retinal or iris scanning, fingerprints, or face recognition.

A simple biometric system translates a human image into a polygon by considering certain features (eyes, nose, ears, etc.) to be vertices and connecting them with line segments. The polygon has distinct vertices but may be degenerate in that the line segments could intersect. Because these polygons are generally created from remote images, there is some uncertainty as to their scale and rotation. Your job is to determine whether or not two polygons are similar; that is, can they be made equal by repositioning, rotating and magnifying them?

Input consists of several test cases. Each test case consists of three lines containing:

f, the number of features
f coordinate pairs giving the vertices of the first polygon
f coordinate pairs giving the vertices of the second polygon
The vertices for both polygons correspond to the same set of features in the same order; for example, right ear tip, chin cleft, right eye, nose, left eye, left ear tip, space between front teeth. Each polygon has f distinct vertices; each vertex is given as an x and y coordinate pair. There are at least three and no more than ten features. Coordinates are integers between -1000 and 1000. A line containing 0 follows the last test case.For each case, output a line “similar” or “dissimilar” as appropriate. The two polygons are similar if, after some combination of translation, rotation, and scaling (but not reflection) both vertices corresponding to each feature are in the same position.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 Sample Input
4
0 0 0 1 1 1 1 0
0 1 1 0 0 -1 -1 0
3
0 0 10 0 10 10
0 0 -10 0 -10 10
3
0 0 10 10 20 20
0 0 11 11 22 22
3
0 0 10 10 20 20
0 0 11 11 20 20 0
Sample Output
similar
dissimilar
similar
dissimilar

思路:
原本的思路是判断所有边是否为比例的,但是还有一个相似问题,百度查看了别人了代码,发现相似问题可以通过角的大小来判断,判断第一个转角是否相等 (同一方向旋转),
公式为 :X1Y2-X2Y1>0 大于0的角度为0-180度 小于0的 180-360之间..虽有判断下 第一个转角是相等就可以解决相似问题了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
using namespace std;
long long q1[1000];
long long p1[1000];
struct point {
int a;
int b;
}p[20], q[20];
int isBili(int i) {
return !(q1[i] * p1[0] == q1[0] * p1[i]);
}
long long distance(int a, int b, int a1, int b1) {
return (b1 - b)*(b1 - b) + (a1 - a)*(a1 - a);
}
int main(int argc, char *argv[]) {
int n;
while (cin >> n&&n != 0) {
int qk = 0, ph = 0;
for (int i = 0; i<n; i++) {
cin >> p[i].a >> p[i].b;
for (int j = 0; j<i; j++) {
p1[ph++] = distance(p[j].a, p[j].b, p[i].a, p[i].b);

}
}
for (int i = 0; i<n; i++) {
cin >> q[i].a >> q[i].b;
for (int j = 0; j<i; j++) {
q1[qk++] = distance(q[j].a, q[j].b, q[i].a, q[i].b);
}
}
long long x1 = p[1].a - p[0].a; long long x2 = p[2].a - p[1].a;
long long y1 = p[1].b - p[0].b; long long y2 = p[2].b - p[1].b;
long long a1 = x1*y2 - x2*y1;
x1 = q[1].a - q[0].a; x2 = q[2].a - q[1].a;
y1 = q[1].b - q[0].b; y2 = q[2].b - q[1].b;
long long a2 = x1*y2 - x2*y1;
int sum = 0;
for (int i = 1; i <qk; i++) {
sum += isBili(i);
}
if (sum == 0 && a2 * a1 >= 0) {
cout << "similar" << endl;
}
else {
cout << "dissimilar" << endl;
}
}
return 0;
}