判断触摸点在一条直线上(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));
}