hihoCoder1040 : 矩形判断

来源:互联网 发布:高德端口修改器 v33 编辑:程序博客网 时间:2024/09/21 06:34

简述

  大体思路是可以出来的,就是先判断能否组成四边形,然后再判断能否组成矩形。
  四边形这部分比较难搞,但是我们有stl啊, 直接自定义一个小于号,然后把所有的点扔进set,最后看下size是不是等于4就好了。
  好,我们已经知道了这是一个四边形,再怎么判断它是否是矩形?
  思来想去啊,似乎计算几何中没有简洁的方法,于是思路回到初中数学。你已经知道了这玩意是四边形,那么首先想到的定理就是“三个角是直角的四边形是矩形”。这个就需要把四条线段首尾相连,然后两两判断是否垂直…好像还是有难度。我们从线段的位置关系来入手,如果对于一条线段,其它三条中有一条是平行于它的,另外两条是垂直于它的,这样是不是矩形?
  考虑证明,首先垂直于它的那两条是平行的,然后它又和另外一条平行,那么就是“两组对边分别平行”。初中数学中有结论,这样就是平行四边形。

代码

//计算几何#include <cstdio>#include <algorithm>#include <cmath>#include <set>#define eps 1e-8using namespace std;struct point{double x, y;}pt[10];struct vec{point p; double x, y;}v[5];set<point> s;vec operator-(point p1, point p2){return (vec){p2,p1.x-p2.x,p1.y-p2.y};}vec operator-(vec v1, vec v2){return (vec){(point){0,0},v1.x-v2.x,v1.y-v2.y};}vec operator+(vec v1, vec v2){return (vec){(point){0,0},v2.x+v1.x,v2.y+v1.y};}double operator*(vec v1, vec v2){return v1.x*v2.y-v2.x*v1.y;}bool operator<(point p1, point p2){return p1.x==p2.x?p1.y<p2.y:p1.x<p2.x;}double dc(vec v1, vec v2){return v1.x*v2.x+v1.y*v2.y;}int main(){    int i, T, c1, c2;    for(scanf("%d",&T);T;T--)    {        s.clear();        for(i=1;i<=8;i++)scanf("%lf%lf",&pt[i].x,&pt[i].y), s.insert(pt[i]);        if(s.size()!=4){printf("NO\n");continue;}        for(i=2;i<=8;i+=2)v[i>>1]=pt[i]-pt[i-1];        c1=c2=0;        for(i=2;i<=4;i++)            if(fabs(dc(v[1],v[i]))<eps)c1++;            else if(fabs(v[1]*v[i])<eps)c2++;        if(c1==2 and c2==1)printf("YES\n");        else printf("NO\n");    }    return 0;}
0 0
原创粉丝点击