和矩形相关的操作

#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#define PI 3.141592654
#define eps 1e-8
using namespace std;
/*********************************************************************/
struct point
{
    int x,y;
    point() {}
    point(int _x,int _y):x(_x),y(_y) {}
} p[40];
double getdis(int a,int b)///两点之间的距离
{
    return sqrt((double)(p[b].y-p[a].y)*(p[b].y-p[a].y)+(p[b].x-p[a].x)*(p[b].x-p[a].x));
}
struct rectangle
{
    int a,b,c,d;
    double h,w,l;
    rectangle(int _a,int _b,int _c,int _d):a(_a),b(_b),c(_c),d(_d)
    {
        h=getdis(_a,_b);
        w=getdis(_a,_c);
        l=getdis(_a,_d);
        if(h>w) swap(h,w);
        if(w>l) swap(w,l);
        if(h>w) swap(h,w);
    }
};
bool isRightAngle(int a,int b,int c) ///判断ab与ac是否构成直角
{
    if((p[b].y-p[a].y)*(p[c].y-p[a].y)==-1*(p[b].x-p[a].x)*(p[c].x-p[a].x))
        return true;
    return false;
}
bool isRectangle(int a,int b,int c,int d) ///判断a,b,c,d是否构成矩形
{
    int rightAngle=0;
    if(isRightAngle(a,b,c)||isRightAngle(a,b,d)||isRightAngle(a,c,d))
        rightAngle++;
    if(isRightAngle(b,a,c)||isRightAngle(b,a,d)||isRightAngle(b,c,d))
        rightAngle++;
    if(isRightAngle(c,a,b)||isRightAngle(c,a,d)||isRightAngle(c,b,d))
        rightAngle++;
    if(isRightAngle(d,a,b)||isRightAngle(d,a,c)||isRightAngle(d,b,c))
        rightAngle++;
    if(rightAngle==4)
        return true;
    else
        return false;
}
double getAngle(int a,int b,int c)///得到ab与ac的夹角
{
    double x=getdis(a,b);
    double y=getdis(a,c);
    double z=getdis(b,c);
    double l=(x+y+z)/2;
    double area=sqrt(l*(l-x)*(l-y)*(l-z));
    if(x*x+y*y-z*z<-eps)
        return (asin(2*area/(x*y))+PI/2);
    else
        return asin(2*area/(x*y));
}
bool isInside(rectangle t,int p)///判断p是否在矩形t内部
{
    double ans=0;
    if(getdis(t.a,t.b)<t.l-eps)
        ans+=getAngle(p,t.a,t.b);
    if(getdis(t.a,t.c)<t.l-eps)
        ans+=getAngle(p,t.a,t.c);
    if(getdis(t.a,t.d)<t.l-eps)
        ans+=getAngle(p,t.a,t.d);
    if(getdis(t.b,t.c)<t.l-eps)
        ans+=getAngle(p,t.b,t.c);
    if(getdis(t.b,t.d)<t.l-eps)
        ans+=getAngle(p,t.b,t.d);
    if(getdis(t.c,t.d)<t.l-eps)
        ans+=getAngle(p,t.c,t.d);
    if(ans-2*PI>-eps&&ans-2*PI<eps)
        return true;
    else return false;
}
bool onSement(int a,int b,int c)///判断c是否在ab线段上
{
    if((p[c].x-p[a].x)*(p[b].y-p[a].y)==(p[b].x-p[a].x)*(p[c].y-p[a].y)&&min(p[a].x,p[b].x)<=p[c].x&&p[c].x<=max(p[a].x,p[b].x)&&
            min(p[a].y,p[b].y)<=p[c].y&&p[c].y<=max(p[a].y,p[b].y))
        return true;
    else
        return false;
}
bool isInEdge(rectangle t,int q)///判断q是否在矩形边框上
{
    if(getdis(t.a,t.b)<t.l-eps&&onSement(t.a,t.b,q))
        return true;
    if(getdis(t.a,t.c)<t.l-eps&&onSement(t.a,t.c,q))
        return true;
    if(getdis(t.a,t.d)<t.l-eps&&onSement(t.a,t.d,q))
        return true;
    if(getdis(t.b,t.c)<t.l-eps&&onSement(t.b,t.c,q))
        return true;
    if(getdis(t.b,t.d)<t.l-eps&&onSement(t.b,t.d,q))
        return true;
    if(getdis(t.c,t.d)<t.l-eps&&onSement(t.c,t.d,q))
        return true;
    return false;
}
double getArea(rectangle t)///得到矩形的面积
{
    return t.h*t.w;
}
/************************************************************************/
vector<rectangle> vc;
int n;
int main()
{
    while(scanf("%d",&n)!=EOF&&n!=0)
    {
        for(int i=0; i<n; ++i)
            scanf("%d%d",&p[i].x,&p[i].y);
        vc.clear();
        for(int i=0; i<n; ++i)
            for(int j=i+1; j<n; ++j)
                for(int u=j+1; u<n; ++u)
                    for(int v=u+1; v<n; ++v)
                        if(isRectangle(i,j,u,v))
                            vc.push_back(rectangle(i,j,u,v));
        double ans=0;
        int tsize=vc.size();
        for(int i=0; i<tsize; ++i)
            for(int j=i+1; j<tsize; ++j)
            {
                if(isInEdge(vc[i],vc[j].a)||isInEdge(vc[i],vc[j].b)||isInEdge(vc[i],vc[j].c)||isInEdge(vc[i],vc[j].d))
                    continue;
                if(isInEdge(vc[j],vc[i].a)||isInEdge(vc[j],vc[i].b)||isInEdge(vc[j],vc[i].c)||isInEdge(vc[j],vc[i].d))
                    continue;
                if(isInside(vc[i],vc[j].a)&&isInside(vc[i],vc[j].b)&&isInside(vc[i],vc[j].c)&&isInside(vc[i],vc[j].d)){
                    ans=max(ans,getArea(vc[i]));
                    continue;
                }
                if(isInside(vc[j],vc[i].a)&&isInside(vc[j],vc[i].b)&&isInside(vc[j],vc[i].c)&&isInside(vc[j],vc[i].d)){
                    ans=max(ans,getArea(vc[j]));
                    continue;
                }
                if(isInside(vc[i],vc[j].a)||isInside(vc[i],vc[j].b)||isInside(vc[i],vc[j].c)||isInside(vc[i],vc[j].d))
                    continue;
                if(isInside(vc[j],vc[i].a)||isInside(vc[j],vc[i].b)||isInside(vc[j],vc[i].c)||isInside(vc[j],vc[i].d))
                    continue;
                ans=max(ans,getArea(vc[i])+getArea(vc[j]));
            }
        if(ans>=-eps&&ans<=eps)
            printf("imp\n");
        else
            printf("%d\n",(int)(ans+0.5));
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 12:41:45

和矩形相关的操作的相关文章

拷贝构造,深度拷贝,关于delete和default相关的操作,explicit,类赋初值,构造函数和析构函数,成员函数和内联函数,关于内存存储,默认参数,静态函数和普通函数,const函数,友元

 1.拷贝构造 //拷贝构造的规则,有两种方式实现初始化. //1.一个是通过在后面:a(x),b(y)的方式实现初始化. //2.第二种初始化的方式是直接在构造方法里面实现初始化. 案例如下: #include<iostream> //如果声明已经定义,边不会生成 class classA { private: int a; int b; public: //拷贝构造的规则,有两种方式实现初始化 //1.一个是通过在后面:a(x),b(y)的方式实现初始化 //2.第二种初始化的方式是直

算法—二叉查找树的相关一些操作及总结

二叉查找树得以广泛应用的一个重要原因就是它能够保持键的有序性,因此它可以作为实现有序符号表API中的众多方法的基础.这使得符号表的用例不仅能够通过键还能通过键的相对顺序来访问键值对.下面,我们要研究有序符号表API中各个方法的实现. 1.最大键和最小键 如果根结点的左链接为空,那么一棵二叉查找树中最小的键就是根结点:如果左链接非空,那么树中的最小键就是左子树中的最小键.简单的循环也能等价实现这段描述,但为了保持一致性我们使用了递归.找出最大键的方法也是类似的,只是变为查找右子树而已. 2.向上取

uva 12299 线段树 点相关的操作模板

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=502&page=show_problem&problem=3720 唯一值得一说的就是shift,变成更新点就行 这道题主要是测试下我做的算法模板 先贴模板 /**************************************************************** 2014.4 By Pilgr

(笔记)Linux内核中内存相关的操作函数

linux内核中内存相关的操作函数 1.kmalloc()/kfree() static __always_inline void *kmalloc(size_t size, gfp_t flags) 内核空间申请指定大小的内存区域,返回内核空间虚拟地址.在函数实现中,如果申请的内存空间较大的话,会从buddy系统申请若干内存页面,如果申请的内存空间大小较小的话,会从slab系统中申请内存空间.有关buddy和slab,请参见<linux内核之内存管理.doc> gfp_t flags 的选项

相关元素操作

五.相关元素操作: var a = document.getElementById("id");找到a: var b = a.nextSibling,找a的下一个同辈元素,注意包含空格:(弟) var b = a.previousSibling,找a的上一个同辈元素,注意包含空格:(兄) var b = a.parentNode,找a的上一级父级元素:(父) var b = a.childNodes,找出来的是数组,找a的下一级子元素:(子) var b = a.firstChild,

iOS与日期相关的操作

// Do any additional setup after loading the view, typically from a nib. //得到当前的日期 注意week1是星期天 NSDate *date = [NSDate date]; NSLog(@"date:%@",date); //得到(24 * 60 * 60)即24小时之前的日期,dateWithTimeIntervalSinceNow: NSDate *yesterday = [NSDate dateWithT

Go语言学习之os包中文件相关的操作(The way to go)

生命不止,继续 go go go !!! 今天跟大家分享学习的是os package,主要是介绍一些跟文件或文件夹相关的操作. os包 Package os provides a platform-independent interface to operating system functionality. The design is Unix-like, although the error handling is Go-like; failing calls return values o

服务相关的操作

二十.服务相关的操作127.0.0.1:6379[2]> DBSIZE    #查看一个库的键值数(integer) 1127.0.0.1:6379[2]> select 0OK127.0.0.1:6379> DBSIZE (integer) 10 127.0.0.1:6379> info   #查看redis服务信息# Serverredis_version:2.8.21redis_git_sha1:00000000略 127.0.0.1:6379> flushdb   

git commit 相关的操作

本地仓库状态相关的操作 1.  git  commit 将从上次提交后到现在这段时间内,暂存区所有的变化提交到版本库中: git  commit  -m '此次提交操作的简要说明(单引号括起来)' commit成功后会显示提交的文件: 2.  git  reset  --hard 撤销上次提交中的所有操作: 原文地址:https://www.cnblogs.com/virgosnail/p/10204693.html