poj 1410
来源:互联网 发布:java语言发展史 编辑:程序博客网 时间:2024/05/18 03:28
这是一个很不错的模版题,题意也很明了,判断线段是否和矩形相交。而所谓“相交”,在计算几何的角度来看,就是线段有一点在矩形内或矩形上。判断的方法如下:
判断线段的两端点是否在矩形内,若是,则线段在矩形内。
判断线段是否与矩形相交,即是否和矩形的四条边中的任意一条边相交(规范相交和不规范相交都算)。
此处是用有向面积法判断点是否在多边形内。最后,看看discuss。。。那个矩形的点有点XXXX,记得x1,x2 和 y1,y2的大小要分别判断,该交换的要交换。
抄了pkkj神的模版,由无限wa瞬间1Y~~~
以下是代码:
- #include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
const double eps=1e-8;
struct point
{
double x,y;
}; - struct line
{
point p1,p2;
}l; - struct poly
{
int n;
double area;
point plist[15];
}rec; - //点乘
- double dotdel(double x1,double y1,double x2,double y2)
{
return x1*x2+y1*y2;
} - //叉乘
- double crossmul(double x1,double y1,double x2,double y2)
{
return x1*y2-x2*y1;
} - //判断是否为0,达到一定精度即认为成立
- int cmpzero(double d)
{
return (fabs(d)<eps)?0:(d>0?1:-1);
} - //右手螺旋定则,1:a在cd右侧,-1:a在cd左侧,0:三点共线
- int cross(point a,point c,point d)
{
return cmpzero(crossmul(a.x-c.x,a.y-c.y,d.x-c.x,d.y-c.y));
} - //在cross(a,c,d)==0的基础上,可判断点a是否在cd内部
- int between(point a,point c,point d)
{
return cmpzero(dotdel(c.x-a.x,c.y-a.y,d.x-a.x,d.y-a.y))!=1;
} - //两线段相交情况:0:不相交,1:规范相交,2:不规范相交(交于端点或重合)
- int seg_intersect(point a,point b,point c,point d)
{
int a_cd=cross(a,c,d);
if(a_cd==0 && between(a,c,d))
return 2;
int b_cd=cross(b,c,d);
if(a_cd==0 && between(a,c,d))
return 2;
int c_ab = cross(c, a, b);
if (c_ab == 0 && between(c, a, b))
return 2;
int d_ab=cross(d,a,b);
if(d_ab==0 && between(d,a,b))
return 2;
if((a_cd^b_cd)==-2 && (c_ab^d_ab)==-2)
return 1;
return 0;
} - //使用有向面积法判断点是否在多边形内
- bool point_in_poly(point p)
{
double s=0.0;
for(int i=0;i<rec.n;i++)
s+=fabs(crossmul(rec.plist[i].x-p.x,rec.plist[i].y-p.y,rec.plist[(i+1)%rec.n].x-p.x,
rec.plist[(i+1)%rec.n].y-p.y));
if(cmpzero(s-rec.area)==0) return true;
else return false;
} - //判断线段是否与多边形相交
- bool rec_seg_intersect()
{
if(point_in_poly(l.p1) && point_in_poly(l.p2))
return 1;
else if(seg_intersect(l.p1,l.p2,rec.plist[0],rec.plist[1])
|| seg_intersect(l.p1,l.p2,rec.plist[1],rec.plist[2])
|| seg_intersect(l.p1,l.p2,rec.plist[2],rec.plist[3])
|| seg_intersect(l.p1,l.p2,rec.plist[3],rec.plist[0]))
return 1;
return 0;
} - //计算多边形面积
- void getarea()
{
double s=rec.plist[0].y*(rec.plist[rec.n-1].x-rec.plist[1].x);
for(int i=1;i<rec.n;i++)
s+=rec.plist[i].y*(rec.plist[i-1].x-rec.plist[(i+1)%rec.n].x);
rec.area=s;
} - int main()
{
int T;
double x1,y1,x2,y2,t;
scanf("%d",&T);
while(T--)
{
scanf("%lf%lf%lf%lf",&l.p1.x,&l.p1.y,&l.p2.x,&l.p2.y);
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
if(x1>x2)
{t=x1;x1=x2;x2=t;}
if(y2>y1)
{t=y1;y1=y2;y2=t;}
rec.n=4;
rec.plist[0].x=x1;rec.plist[0].y=y1;
rec.plist[1].x=x1;rec.plist[1].y=y2;
rec.plist[2].x=x2;rec.plist[2].y=y2;
rec.plist[3].x=x2;rec.plist[3].y=y1;
getarea();
puts(rec_seg_intersect()?"T":"F");
}
return 0;
}
- poj 1410
- poj 1410
- POJ 1410
- POJ 1410
- poj 1410
- poj 1410
- poj 1410
- poj 1410
- POJ 1410 Intersection
- POJ 1410 计算几何
- poj 1410 Intersection
- POJ 1410 Intersection
- poj 1410 Intersection
- POJ 1410 Intersection
- POJ 1410 Intersection
- poj 1410 Intersection
- POJ 1410 Intersection
- POJ 1410 Intersection
- 线程同步
- 验证码
- 重要的时候记录一笔
- 毕业倒计时
- 昨天,今天,明天! Unix系统的40年
- poj 1410
- javascript高级应用
- 修复主页
- 关于perl中DBD for Oracle的安装
- MS-SQL删除数据库中的重复行
- SQL触发器
- 【转载】android开发新浪微博客户端 完整攻略
- 移动开发的产业链已明朗化
- C#调用存储过程简单完整例子