二维空间中两线段的交点
已知线段1的两点为P1(h1,v1),P2(h2,v2), 线段2的两点为P3(h3,v3),P4(h4,v4), 则两线段的交点:
float hinters;float vinters;//交点
bool flag=GetTwoLineSegmentIntersection(h1,v1,h2,v2,h3,v3,h4,v4,hinters,vinters);
if(flag)
{
//交点为(hinters,vinters)
}
else
{
//无交点
}
bool CMesh::GetTwoLineSegmentIntersection(float h1,float v1,float h2,float v2,
float h3,float v3,float h4,float v4,
float &hinters,float &vinters)
{
//第一条直线
float a11,a12,b1;
if (h1!=h2)
{
float k=(v2-v1)/(h2-h1);
float b=v2-k*h2;
a11=k;
a12=-1.0f;
b1=-b;
}
else//两值相等,无斜率
{
a11=1.0f;
a12=0.0f;
b1=h1;
}
//第二条直线
float a21,a22,b2;
if (h3!=h4)
{
float k=(v4-v3)/(h4-h3);
float b=v4-k*h4;
a21=k;
a22=-1.0f;
b2=-b;
}
else
{
a21=1.0f;
a22=0.0f;
b2=h3;
}
//a11x+a12y=b1;
//a21x+a22y=b2;
//交点计算
bool flag=GetTwoLineIntersection(a11,a12,b1,a21,a22,b2,hinters,vinters);
if (!flag)
{
return false;
}
else
{
if (!(
((hinters-h1)*(hinters-h2)<=0)
&&((vinters-v1)*(vinters-v2)<=0)
&&((hinters-h3)*(hinters-h4)<=0)
&&((vinters-v3)*(vinters-v4)<=0)
)
)//不在线段上
{
return false;
}
}
return true;
}
求解直线交点,依据克莱姆法则,即为求解两个未知数两个方程的方程组,其函数如下,
bool GetTwoLineIntersection(float _a1,float _b1,float _c1,float _a2,float _b2,float _c2,float &x,float &y)
{
//_a1x+_b1y=_c1;---(1)
//_a2x+_b2y=_c2;---(2)
//
if (_c1==0&&_c2==0)
{
//2个未知数2个方程组成的齐次方程组求解
//系数矩阵B
//| _a1 _b1 |
//| _a2 _b2 |
float DB=_a1*_b2-_a2*_b1;
if (DB!=0)//有唯一零解
{
x=0.0f;
y=0.0f;
return true;
}
else//有无数解:共线
{
x=0.0f;
y=0.0f;
return false;
}
}
else
{
//2个未知数2个方程组成的非齐次方程组求解
//系数矩阵B
//| _a1 _b1 |
//| _a2 _b2 |
//
float DB=_a1*_b2-_a2*_b1;
if (DB!=0)//有唯一解
{
float dD1 = _c1 * _b2 - _c2 * _b1;
float dD2 = _a1 * _c2 - _a2 * _c1;
x = dD1 / DB;
y= dD2 / DB;
return true;
}
else//有无数解或者无解:共线或平行
{
x=0.0f;
y=0.0f;
return false;
}
}
return false;
}