欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

判断触摸点在一条直线上(Swift 方法)

程序员文章站 2022-04-01 17:56:12
...

最近在做扫地机项目,其中有个虚拟墙的功能,我们需要绘制并移动虚拟墙,这牵涉到一个知识点:判断我们的手指触摸点在虚拟墙(直线)上,研究了很久,找到一个方法,记录下来,以备后续之用:

 /* 判断触摸点在虚拟墙(直线)上*/
    func pointIsinLine(point:CGPoint,startpoint p0:CGPoint,endpoint p1:CGPoint) -> Bool {
        //设置一个点到线段的允许的最大值
        let maxAllowOffsetLength:Float = 10
        //通过直线方程的两点式计算出一般式的ABC参数
        let A = p1.y - p0.y
        let B = p0.x - p1.x
        let C = p1.x * p0.y - p0.x * p1.y
        
        //带入点到直
        let sqrt:Float = sqrtf(powf(Float(A), 2) + powf(Float(B),2))
        
        var dis:Float = fabsf( Float(A * point.x + B * point.y + C) / sqrt )
        //果该距离大于允许值说明则不在线段上
        if dis > maxAllowOffsetLength || dis.isNaN {
            return false
        }else {
            //否则我们要进一步判断,投影点是否在线段上,根据公式求出投影点的X坐标jiaoX
            let D = (A * point.y - B * point.x)
            let jiaoX = -(A * C + B * D) / (pow(B, 2) + pow(A, 2))
            let t = (jiaoX - p0.x) / (p1.x - p0.x)
            if t > 1 || t.isNaN {
                //最小距离为到p1点的距离
                dis = Float(LengthOfTwoPoint(point1: p1, point2: point))
            }else if (t < 0){
                //最小距离为到p2点的距离
                dis = Float(LengthOfTwoPoint(point1: p0, point2: point))
            }
            //再次判断真正的最小距离是否小于允许值,小于则该点在直线上,反之则不在
            if (dis <= maxAllowOffsetLength) {
                Log("在此直线上")
                return true
            }else{
                return false
            }
        }
    }
    
    /* 这里是求两点距离公式 */
    func LengthOfTwoPoint( point1:CGPoint, point2:CGPoint) -> CGFloat{
        return sqrt(pow(point1.x - point2.x, 2) + pow(point1.y - point2.y, 2));
    }