快速计算2D空间中两条线段是否相交
每一条线段都落于一条对应的直线上,且有两个端点。
2D空间中判定两条线段是否相交极其常用和有用。
这里采用几何原理来判定两条线段是否相交。
判定的原理如下:
如果线段A的两个端点,在线段B所在直线的两侧, 而线段B的两个端点也在线段A所在直线的两侧,这两条线段就相交。
关于Vector_2D: http://www.cnblogs.com/vilyLei/articles/1567703.html
样例演示:http://www.cnblogs.com/vilyLei/articles/1386711.html
这里给出了一个基于as3基本的线段类得实现,如有错误请指出:
//
package
{
//import simple2d.primitives.Vector_2D;
/**
通过两个端点定义一个简单的线段
*/
public class LineSegment{
// 定义线段的两个端点,通过他们和一些基本规定,即可求得线段的法向和切向
public var pA_v:Vector_2D = new Vector_2D();
public var pB_v:Vector_2D = new Vector_2D();
//
private var temp_0_v:Vector_2D = new Vector_2D();
private var temp_1_v:Vector_2D = new Vector_2D();
private var temp_2_v:Vector_2D = new Vector_2D();
public function LineSegment(){
}
// 对方线段是否和线段自身所在的直线相交,但是不区分平行的状况
public function intersectExtLine(ls:LineSegment):Boolean{
//取得自身端点pA_v到端点pB_v的矢量,方向等同于自身的切向
temp_0_v.x = pB_v.x - pA_v.x;
temp_0_v.y = pB_v.y - pA_v.y;
//取得目标线段的两个端点到自身端点pA_v对应的矢量
temp_1_v.x = pA_v.x - ls.pA_v.x;
temp_1_v.y = pA_v.y - ls.pA_v.y;
//
temp_2_v.x = pA_v.x - ls.pB_v.x;
temp_2_v.y = pA_v.y - ls.pB_v.y;
// 用矢量叉乘判断目标线段的两个端点是否在自己所在的直线的两侧
return (temp_1_v.cross( temp_0_v ) * temp_2_v.cross( temp_0_v )) <= 0;
}
/**
用于检测ls线段是否和自己相交
*/
public function intersect(ls:LineSegment):Boolean{
//检测自己的延长线是否和ls线段相交
if( intersectExtLine( ls ) ){
//检测ls的延长线是否和自己的线段相交或重合
return ls.intersectExtLine( this );
}
return false;
}
}
}
//
package
{
//import simple2d.primitives.Vector_2D;
/**
通过两个端点定义一个简单的线段
*/
public class LineSegment{
// 定义线段的两个端点,通过他们和一些基本规定,即可求得线段的法向和切向
public var pA_v:Vector_2D = new Vector_2D();
public var pB_v:Vector_2D = new Vector_2D();
//
private var temp_0_v:Vector_2D = new Vector_2D();
private var temp_1_v:Vector_2D = new Vector_2D();
private var temp_2_v:Vector_2D = new Vector_2D();
public function LineSegment(){
}
// 对方线段是否和线段自身所在的直线相交,但是不区分平行的状况
public function intersectExtLine(ls:LineSegment):Boolean{
//取得自身端点pA_v到端点pB_v的矢量,方向等同于自身的切向
temp_0_v.x = pB_v.x - pA_v.x;
temp_0_v.y = pB_v.y - pA_v.y;
//取得目标线段的两个端点到自身端点pA_v对应的矢量
temp_1_v.x = pA_v.x - ls.pA_v.x;
temp_1_v.y = pA_v.y - ls.pA_v.y;
//
temp_2_v.x = pA_v.x - ls.pB_v.x;
temp_2_v.y = pA_v.y - ls.pB_v.y;
// 用矢量叉乘判断目标线段的两个端点是否在自己所在的直线的两侧
return (temp_1_v.cross( temp_0_v ) * temp_2_v.cross( temp_0_v )) <= 0;
}
/**
用于检测ls线段是否和自己相交
*/
public function intersect(ls:LineSegment):Boolean{
//检测自己的延长线是否和ls线段相交
if( intersectExtLine( ls ) ){
//检测ls的延长线是否和自己的线段相交或重合
return ls.intersectExtLine( this );
}
return false;
}
}
}
//
这里的算法不限于实现语言。
如果你想计算他们相交的交点,原理请见:http://www.cnblogs.com/vilyLei/articles/2191514.html

浙公网安备 33010602011771号