POJ 1931 Biometrics (计算几何、标量积、向量积)

来源:互联网 发布:通达信炒股软件好用吗 编辑:程序博客网 时间:2024/05/19 23:59

题目看起来比较有趣,模拟人脸识别,指纹识别。具体是这样的:用两组点分别表示两个几何图形,判断这两个几何图形是否相似。“相似“的标准是:通过旋转和放大缩小操作能过使两个图形相等。

判断旋转要用到向量积和标量积,光用一个是不够的,因为 sin 和 cos 函数在 0 到 360 度定义域内的值不是唯一的。

判断放大缩小,只要算向量的模就可以。

#include<iostream>#include<cmath>#define EPS 1e-9#define feq(a, b) (fabs((a)-(b)) < EPS)using namespace std;typedef struct{double x, y;} POINT;POINT vect[2][20];double dist(POINT a, POINT b){return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));}double crossProduct(POINT a, POINT b){POINT o = {0, 0};return ((a.x * b.y) - (a.y * b.x)) / (dist(a, o) * dist(b, o));}double dotProduct(POINT a, POINT b){POINT o = {0, 0};return ((a.x * b.x) + (a.y * b.y)) / (dist(a, o) * dist(b, o));}void print(POINT a[], int n){for(int i = 0; i < n; i++)cout << a[i].x << " " << a[i].y << endl;}int main(){int n;while(cin >> n){if(n == 0)break;for(int j = 0; j < 2; j++){ //inputPOINT origin;cin >> origin.x >> origin.y;for(int i = 0 ; i < n - 1; i++){POINT temp, temp2;cin >> temp.x >> temp.y;temp2 = temp;temp.x -= origin.x;temp.y -= origin.y;vect[j][i] = temp;origin = temp2;}}bool eq = true;double angle = crossProduct(vect[0][0], vect[1][0]);//判断旋转double angle1 = dotProduct(vect[0][0], vect[1][0]);for(int i = 1; i < n - 1; i++){double temp = crossProduct(vect[0][i], vect[1][i]);double temp1 = dotProduct(vect[0][i], vect[1][i]);if(!feq(temp, angle) || !feq(temp1, angle1)){eq = false;break;}}POINT o = {0, 0};double ratio = dist(vect[0][0], o)/dist(vect[1][0], o);//判断伸缩for(int i = 1; i < n - 1; i++){double temp = dist(vect[0][i], o)/dist(vect[1][i], o);if(!feq(temp, ratio)){eq = false;break;}}if(eq)cout << "similar" << endl;elsecout << "dissimilar" << endl;}}




原创粉丝点击