计算几何入门题,直接模拟即可,这个题关键是判断四个点的位置,我的方法如下:
if(SegmentProperIntersection(z[1],z[2], z[3], z[4])) A = z[1], D = z[2], C = z[3], B = z[4], flag = 1;
else if(SegmentProperIntersection(z[1], z[3], z[2], z[4])) A = z[1], D = z[3], C = z[2], B = z[4], flag = 1;
else if(SegmentProperIntersection(z[1], z[4], z[2], z[3])) A = z[1], D = z[4], C = z[2], B = z[3], flag = 1;
这样四个点的位置为AD与BC相交,当然这么判断还是不够,我就没考虑到这个点,结果一直wa,如果是凹四边形呢,所以凹四边形的情况需要用flag判断。
位置判断结束后,就要判断平行线tmp,
if(!flag || tmp == 0 ) 普通四边形
else if ( tmp == 1 ) 梯形
else if (tmp == 2) {
if 有一个角是直角 {
if 邻边相等 正方形
else 矩形
}
else {
if 邻边相等 菱形
else 平行四边形
}
}
/*************************************************************************
> File Name: UVa11800.cpp
> Author: AcToy
> Mail: ycsgldy@163.com
> Created Time: 2013年07月18日 星期四 21时00分45秒
************************************************************************/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
using namespace std;
typedef unsigned int u32;
typedef long long i64;
typedef unsigned long long u64;
typedef vector<int> IV;
typedef vector<bool> BV;
typedef pair<int,int> II;
typedef vector<II> IIV;
#define For(t,v,c) for(t::const_iterator v=c.begin(); v!=c.end(); ++v)
const int INF = 0x7FFFFFFF;
const double eps = 1E-10;
const double PI = acos(-1);
struct Point {
double x, y;
Point(double x = 0, double y = 0):x(x), y(y) { }
};
typedef Point Vector;
Vector operator + (const Vector& A, const Vector& B) { return Vector(A.x + B.x, A.y + B.y); };
Vector operator - (const Point& A, const Point& B) { return Vector(A.x - B.x, A.y - B.y); }
Vector operator * (const Vector& A, double p) { return Vector(A.x * p, A.y * p); }
int dcmp(double x) {
if(fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
//bool operator < (const Point& a, const Point& b) { dcmp(a.x - b.x) < 0 || (dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) < 0); }
double Dot(const Vector& A, const Vector& B) { return A.x * B.x + A.y * B.y; }
double Length(const Vector& A) { return sqrt(Dot(A, A)); }
double Angle(const Vector& A, const Vector& B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
double Cross(const Vector& A, const Vector& B) { return A.x * B.y - A.y * B.x; }
bool SegmentProperIntersection(const Point& a1, const Point& a2, const Point& b1, const Point& b2) {
double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1), c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1, a2 - b1);
return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
}
Point read_point() {
double x, y;
scanf("%lf%lf", &x, &y);
return Point(x, y);
}
int main() {
Point A, B, C, D, z[6];
int Case, cnt;
scanf("%d", &Case);
for(cnt = 1; cnt <= Case; ++cnt) {
bool flag = 0;
for(int i = 1; i <= 4; ++i)
z[i] = read_point();
if(SegmentProperIntersection(z[1],z[2], z[3], z[4])) A = z[1], D = z[2], C = z[3], B = z[4], flag = 1;
else if(SegmentProperIntersection(z[1], z[3], z[2], z[4])) A = z[1], D = z[3], C = z[2], B = z[4], flag = 1;
else if(SegmentProperIntersection(z[1], z[4], z[2], z[3])) A = z[1], D = z[4], C = z[2], B = z[3], flag = 1;
int tmp = 0;
Vector Vab = B - A, Vac = C - A, Vcd = D - C, Vbd = D - B;
if(dcmp(Cross(Vab, Vcd)) == 0) tmp++;
if(dcmp(Cross(Vac, Vbd)) == 0) tmp++;
double Lab = Length(Vab), Lac = Length(Vac), Lcd = Length(Vcd), Lbd = Length(Vbd);
printf("Case %d: ", cnt);
if(!flag || tmp == 0) printf("Ordinary Quadrilateral\n");
else if(tmp == 1) printf("Trapezium\n");
else if(tmp == 2) {
if(dcmp(Dot(Vab, Vac)) == 0) {
if(dcmp(Lac - Lab) == 0) printf("Square\n");
else printf("Rectangle\n");
}
else if(dcmp(Lab - Lac) == 0) printf("Rhombus\n");
else printf("Parallelogram\n");
}
}
return 0;
}