目录
运算符重载
struct point{
int x,y;
point(int x = 0,int y = 0):x(x),y(y){}
};
typedef point vector;
vector operator +(vector a,vector b){
return vector(a.x + b.x,a.y + b.y);
}
vector operator -(point a,point b){
return vector(a.x-b.x,a.y-b.y);
}
vector operator *(vector a,double p){
return vector(a.x * p,a.y * p);
}
vector operator /(vector a,double p){
return vector(a.x / p,a.y / p);
}
相等判断
int dcmp(double x){
if(fabs(x) < eps) return 0;
else return x < 0 ? -1:1;
}
bool operator == (const Point &a, const Point &b){
return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;
}
点积叉积(线线关系)
int dot(vector a,vector b){
return a.x * b.x + a.y * b.y;
}
int cross(vector a,vector b){
return a.x * b.y - a.y * b.x;
}//右手定则 顺逆时针->正负
叉积作用:
1:通过结果的正负判断两矢量之间的顺逆时针关系
若 a x b > 0表示a在b的顺时针方向上
若 a x b < 0表示a在b的逆时针方向上
若 a x b == 0表示a在b共线,但不确定方向是否相同
2:判断折线拐向,可转化为判断第三点在前两的形成直线的顺逆时针方向,然后判断拐向。
3:判断一个点在一条直线的那一侧,同样上面的方法。
4:判断点是否在线段上,可利用叉乘首先判断是否共线,然后在判断是否在其上。
5:判断两条直线是否想交(跨立实验)
根据判断点在直线那一侧我们可以判断一个线段的上的两点分别在另一个线段的两侧,当然这是不够的,因为我们画图发现这样只能够让直线想交,而不是线段,所以我们还要对另一条线段也进行相同的判断就ok。
判断两直线间的关系 && 求交点
先判断两条直线是不是同线,不是的话再判断是否平行,再不是的话就只能是相交的,求出交点。
同线?由叉积的原理知道如果p1,p2,p3共线的话那么(p2-p1)X(p3-p1)=0。因此如果p1,p2,p3共线,p1,p2,p4共线,那么两条直线共线。求叉积,叉积为0说明共线。
平行?由向量可以判断出两直线是否平行。如果两直线平行,那么向量p1p2、p3p4也是平等的。即((p1.x-p2.x)*(p3.y-p4.y)-(p1.y-p2.y)*(p3.x-p4.x))==0说明向量平等。
如何求出交点?这里也用到叉积的原理。假设交点为p0(x0,y0)。则有:
(p1-p0)X(p2-p0)=0
(p3-p0)X(p2-p0)=0
展开后即是
(y1-y2)x0+(x2-x1)y0+x1y2-x2y1=0
(y3-y4)x0+(x4-x3)y0+x3y4-x4y3=0
将x0,y0作为变量求解二元一次方程组。
假设有二元一次方程组
a1x+b1y+c1=0;
a2x+b2y+c2=0
那么
x=(c1*b2-c2*b1)/(a2*b1-a1*b2);
y=(a2*c1-a1*c2)/(a1*b2-a2*b1);
因为此处两直线不会平行,所以分母不会为0。
重合 || 平行
int cross(int x_1,int y_1,int x_2,int y_2){
return (x_1 * y_2) - (x_2 * y_1);
}
bool Line(){//共线
int A = cross(x33 - x11,y33 - y11,x22 - x11,y22 - y11);
int B = cross(x11 - x44,y11 - y44,x33 - x44,y33 - y44);
if(!A && !B) return 1;
return 0;
}
bool None(){//平行
if(cross(x22 - x11,y22 - y11,x44 - x33,y44 - y33) == 0) return 1;
return 0;
}