Swift UIBelzierpath-path.contains(userTouchPoint)只能检测userTouchPoint.y是否正好位于路径y的位置
我有这样一条路径(红色中间线),它是从Swift UIBelzierpath-path.contains(userTouchPoint)只能检测userTouchPoint.y是否正好位于路径y的位置,swift,uibezierpath,Swift,Uibezierpath,我有这样一条路径(红色中间线),它是从 func drawALine(point1:CGPoint,point2:CGPoint)->CAShapeLayer{ let path = UIBezierPath() path.move(to: point1) path.addLine(to: point2) let shapeLayer = CAShapeLayer() shapeLayer.path =
func drawALine(point1:CGPoint,point2:CGPoint)->CAShapeLayer{
let path = UIBezierPath()
path.move(to: point1)
path.addLine(to: point2)
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 10
self.layer.addSublayer(shapeLayer)
return shapeLayer
}
因为我有多条线,所以我必须检测我用这个触摸的是哪一条
for each in RulerModelArray{
if (!(each.midPath.path?.contains(touchPoint))!) {
print("not contain")
} else {
print("contained",each.ID)
}
}
问题是如果我的点1
/点2
y是450,而我的接触点.y是450.00001,那么它将不会被检测到。只有大约1%我不能在完美的地方点击
用这个测试:
let testPoint:CGPoint = CGPoint(x: touchPoint.x, y: touchPoint.y + 0.0001 )
for each in RulerModelArray{
if (!(each.midPath.contains(testPoint))) {
print("not contain")
} else {
print("contained",each.ID)
}
}
///always return not contain
在shapeLayer.lineWidth=10
中是否有我可以检测到的路径?您可以使用此选项
检查CGPoint是否在UIBezierPath的边界内
适用于水平线,因为水平线的大小高度为0
extension UIBezierPath{
func hasForHorizontalLine(pt point: CGPoint) -> Bool{
let bezierRect = bounds
let origin = bezierRect.origin
let size = bezierRect.size
if origin.x <= point.x , origin.x + size.width >= point.x, origin.y - lineWidth * 0.5 <= point.y , origin.y + lineWidth * 0.5 >= point.y{
return true
}
else{
return false
}
}
}
扩展UIBezierPath{
func HASFORHORIONTALLINE(pt点:CGPoint)->Bool{
设bezierRect=边界
让origin=bezierrrect.origin
let size=bezierrrect.size
如果origin.x=point.x,origin.y-线宽*0.5=point.y{
返回真值
}
否则{
返回错误
}
}
}
这是一种更通用的方法 适用于任何类型的直线 通过计算从接触点到目标线的距离
extension CGPoint{
// tolerance, should by the lineWidth of a UIBezierPath
func contained(byStraightLine start: CGPoint,to end: CGPoint, tolerance width: CGFloat) -> Bool{
return distance(fromLine: start, to: end) <= width * 0.5
}
func distance(fromLine start: CGPoint,to end: CGPoint) -> CGFloat{
let a = end.y - start.y
let b = start.x - end.x
let c = (start.y - end.y) * start.x + ( end.x - start.x ) * start.y
return abs(a * x + b * y + c)/sqrt(a*a + b*b)
}
}
扩展点{
//公差,应为UIBezierPath的线宽
包含func(铁路线起点:CGPoint,终点:CGPoint,公差宽度:CGFloat)->Bool{
返回距离(从行:开始,到:结束)CGFloat{
设a=end.y-start.y
设b=start.x-end.x
设c=(start.y-end.y)*start.x+(end.x-start.x)*start.y
返回abs(a*x+b*y+c)/sqrt(a*a+b*b)
}
}
each.midPath.path?
是一个CGPath,似乎我不能将边界
与CGPath一起使用。而我的midPath
是一个CAShapeLayer,它总是将所有内容返回0给我