您的位置:首页 > 其它

hdu_1086 You can Solve a Geometry Problem too(计算几何)

2014-01-07 14:22 369 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1086

分析:简单计算几何题,相交判断直接用模板即可。

思路:将第k条直线与前面k-1条直线进行相交判断,因为题目中不排除多条直线相交于同一个点的重复情况。

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <math.h>
using namespace std;
const double eps = 1e-8;
const double PI = acos(-1.0);  //比直接写3.1415926精确

int sgn(double x)              //三态函数,精确度提高
{
if(fabs(x) < eps)return 0;
else return x<0? -1:1;
}

struct Point
{
double x,y;
Point(){}
Point(double _x,double _y)  //带参构造函数
{
x = _x;y = _y;
}
Point operator -(const Point &b)const  //点相减
{
return Point(x - b.x,y - b.y);
}
double operator ^(const Point &b)const  //叉积(外积)
{
return x*b.y - y*b.x;
}
double operator *(const Point &b)const //点积
{
return x*b.x + y*b.y;
}
void transXY(double B)            //绕原点旋转角度B(弧度值),后x,y的变化
{
double tx = x,ty = y;        //
x = tx*cos(B) - ty*sin(B);
y = tx*sin(B) + ty*cos(B);
}
};
struct Line
{
Point s,e;
Line(){}
Line(Point _s,Point _e)
{
s = _s;e = _e;
}
//两直线相交求交点
//第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交
//只有第一个值为2时,交点才有意义
pair<int,Point> operator &(const Line &b)const
{
Point res = s;
if(sgn((s-e)^(b.s-b.e)) == 0)
{
if(sgn((s-b.e)^(b.s-b.e)) == 0)
return make_pair(0,res);//重合
else return make_pair(1,res);//平行
}
double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
res.x += (e.x-s.x)*t;
res.y += (e.y-s.y)*t;
return make_pair(2,res);
}
};
Point ms,me;
Line  ml[120];

//*两点间距离
double dist(Point a,Point b)
{
return sqrt((a-b)*(a-b));
}
//*判断线段相交
bool inter(Line l1,Line l2)
{
return
max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&
max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&
max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&
max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&
sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&
sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;
}

int main()
{
int n;
int ans;
while(scanf("%d",&n),n){
ans=0;
for(int i=0;i<n;i++){
scanf("%lf%lf%lf%lf",&ms.x,&ms.y,&me.x,&me.y);
ml[i].s=ms; ml[i].e=me;
}
for(int i=1;i<n;i++)
for(int j=0;j<i;j++){
if(inter(ml[i],ml[j])) ans++;
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: