快速计算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;
            
        }
    }
}
//

 

这里的算法不限于实现语言。

如果你想计算他们相交的交点,原理请见:http://www.cnblogs.com/vilyLei/articles/2191514.html 

posted @ 2011-09-30 10:16  vily_雷  阅读(1005)  评论(0)    收藏  举报