这些代码未经过题目测试,存在安全隐患。。。。
struct Line
{
Point s,e;
Line(){}
//两点
Line(const Point ss,const Point ee)
{
s=ss,e=ee;
}
//点斜
Line(const Point p,const double angle)
{
s=p;
if(sgn(angle-pi/2)==0)
e=(s+Point(0,1));
else e=(s+Point(1,tan(angle)));
}
//ax+by+c=0
Line(double a,double b,double c)
{
if(sgn(a)==0)
{
s=Point(0,-c/b);
e=Point(1,-c/b);
}
else if(sgn(b)==0)
{
s=Point(-c/a,0);
e=Point(-c/a,1);
}
else
{
s=Point(0,-c/b);
e=Point(1,(-c-a)/b);
}
}
void input(void)
{
s.input();
e.input();
}
void output(void)
{
s.output();
e.output();
}
//两点应该是由s——>e,
//由x负向指向x正向。
void adjust(void)
{
if(e<s) swap(s,e);
}
//判断两线段是否重合
bool operator == (Line b)
{
adjust(),b.adjust();
return (s==b.s)&&(e==b.e);
}
//求线段长度
double len(void)
{
return s.dis(e);
}
//返回直线倾斜角
//0<=angle<pi
double angle(void)
{
double k=atan2(e.y-s.y,e.x-s.x);
if(sgn(k)<0) k+=pi;
if(sgn(k-pi)==0) k-=pi;
return k;
}
//点和直线的关系
//1 在左侧 (在s——>e的逆时针侧)
//2 在右侧 (在s——>e的顺时针侧)
//3 在直线上
int relation(const Point &p)
{
int c=sgn((p-s)^(e-s));
if(c<0) return 1;
else if(c>0) return 2;
else return 3;
}
//点是否在线段上
bool p_is_on_seg(const Point &p)
{
return sgn((p-s)^(e-s))==0&&sgn((p-s)*(p-e))<=0;
}
//两向量平行,对应直线平行或者重合
bool parallel(const Line &v)
{
return sgn((e-s)^(v.e-v.s))==0;
}
//两线段相交判断
//2 规范相交
//1 非规范相交
//0 不相交
int seg_cross_seg(const Line &v)
{
int d1=sgn((e-s)^(v.s-s));
int d2=sgn((e-s)^(v.e-s));
int d3=sgn((v.e-v.s)^(s-v.s));
int d4=sgn((v.e-v.s)^(e-v.s));
if((d1^d2)==-2&&(d3^d4)==-2) return 2;
d1=(d1==0&&sgn((v.s-s)*(v.s-e))<=0);
d2=(d2==0&&sgn((v.e-s)*(v.e-e))<=0);
d3=(d3==0&&sgn((s-v.s)*(s-v.e))<=0);
d4=(d4==0&&sgn((e-v.s)*(e-v.e))<=0);
return d1||d2||d3||d4;
}
//直线和线段相交
//2 规范相交
//1 非规范相交
//0 不相交
int line_cross_seg(const Line &v)
{
int d1=sgn((e-s)^(v.s-s));
int d2=sgn((e-s)^(v.e-s));
if(d1^d2==-2) return 2;
return (d1==0||d2==0);
}
//两直线的关系
//0 平行
//1 重合
//2 相交
int line_cross_line(Line &v)
{
if((*this).parallel(v))
return v.relation(s)==3;
return 2;
}
//求两直线的交点
//要保证两直线不平行或重合
Point cross_point(Line v)
{
double a1=(v.e-v.s)^(s-v.s);
double a2=(v.e-v.s)^(e-v.s);
return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
}
//点到直线的距离
double dis_point_to_line(const Point &p)
{
return abs((p-s)^(e-s))/len();
}
//点到线段的距离
double dis_point_to_seg(const Point &p)
{
if(sgn((p-s)*(e-s))<0||sgn((p-e)*(s-e))<0)
return min(p.dis(s),p.dis(e));
return dis_point_to_line(p);
}
//返回线段到线段的距离
//前提是两线段不相交,相交就是0了
double dis_seg_to_seg(Line &v)
{
double s1=min(dis_point_to_seg(v.s),dis_point_to_seg(v.e));
double s2=min(v.dis_point_to_seg(s),v.dis_point_to_seg(e));
return min(s1,s2);
}
//返回点p在直线上的投影
Point point_proj_line(Point &p)
{
return s+(((e-s)*((e-s)*(p-s)))/((e-s).len2()));
}
//返回点p关于直线的对称点
Point point_sym_line(Point &p)
{
Point q=point_proj_line(p);
return Point(2*q.x-p.x,2*q.y-p.y);
}
};