首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >找出路径上触摸的位置(按百分比)

找出路径上触摸的位置(按百分比)
EN

Stack Overflow用户
提问于 2015-12-08 13:12:39
回答 2查看 351关注 0票数 0

我有一个CGPath,在这条路上我探测到触点。这条路基本上是一条线或一条曲线,但它没有被填满。这个想法是用户画路径,所以不管用户在哪抚摸路径,我都想用不同的笔画/颜色等来画路径。

首先,为了查找路径中是否有触点,并给用户一些出错的空间,我使用了CGPathCreateCopyByStrokingPathCGPointInsidePath。这个很好用。

接下来,我需要找到用户抚摸的路径有多远。这就是今天的问题。

当这件事完成后,我得到了一个33%的答案,然后我将成为路径上的strokeEnd的一个简单任务。(两个副本,一个完整的路径,一个顶部的strokeEnd设置为用户用手指抚摸的完整路径的百分比)。

有什么想法吗?如何找到用户抚摸手指的路径?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-08 15:25:23

我有一个实用工具类GHPathUtilies.m,它包括一个方法:

代码语言:javascript
复制
+(CGFloat) totalLengthOfCGPath:(CGPathRef)pathRef

所有这些都是用Objective编写的,但是您可以使用相同的技术沿着路径元素走,使用CGPathApply,直到足够近,或者已经通过了目标点。一般的思路是将每个元素之间的曲线分解成小的线段,并保持每段长度的运行和。

当然,如果路径本身是双倍的,你必须弄清楚哪一点是触点。

票数 0
EN

Stack Overflow用户

发布于 2015-12-13 21:46:41

我已经在这方面做了很长时间的工作,并想分享我的答案(我是问这个问题的人)。

  1. 我想检测沿着路径的接触(例如,Bezier曲线)。问题是,它只能告诉您是否触碰到路径,但不能告诉您在哪里(使用CGPathContainsPoint)。
  2. 为了避免用户精确地点击路径,使用CGPathCreateCopyByStrokingPath创建一个更胖的版本),所以这是一个检查触摸的版本。
  3. 主要的问题仍然是,沿着这条路,触碰击中了哪里。我所做的就是用最小间距的CGPathCreateCopyByDashingPath创建虚线路径副本。此路径从未实际显示。然后,使用CGPathApply保存数组中的每个path元素,得到它的每个部分。
  4. 当检测到触摸并位于"fat路径“内时,我只需循环遍历路径-破折号元素数组,检查每个路径-破折号元素的起始点的距离(只是普通的毕达哥拉斯)。

如果触点是最接近第14‘元素的,并且有140个元素,那就意味着我们在这个过程中是10%。

  1. 现在我们有了这个百分比。我现在想要的是把这条路画得尽可能远。我尝试在路径上使用建议的strokeEnd属性。这与我计算的百分比完全不相符。实际上,在我看来,这是相当不准确的。或者我的计算是。

总之,由于我们已经有了所有的path元素,并且知道应该在哪个元素处停下来(第14个元素),我所做的就是使用path元素构建一个新的路径。因为我不想要虚线路径(这只是找出触摸在长连续路径上的位置的一个技巧),所以我跳过了所有的moveTo路径元素(除了第一个)。这将创造一条持续的道路。

CGPathApply - by request

代码语言:javascript
复制
// MARK: - Stuff for CGPathApply

typealias MyPathApplier = @convention(block) (UnsafePointer<CGPathElement>) -> Void
// http://stackoverflow.com/questions/24274913/equivalent-of-or-alternative-to-cgpathapply-in-swift
// Note: You must declare MyPathApplier as @convention(block), because
// if you don't, you get "fatal error: can't unsafeBitCast between
// types of different sizes" at runtime, on Mac OS X at least.

func myPathApply(path: CGPath!, block: MyPathApplier) {
    let callback: @convention(c) (UnsafeMutablePointer<Void>, UnsafePointer<CGPathElement>) -> Void = { (info, element) in
        let block = unsafeBitCast(info, MyPathApplier.self)
        block(element)
    }

    CGPathApply(path, unsafeBitCast(block, UnsafeMutablePointer<Void>.self), unsafeBitCast(callback, CGPathApplierFunction.self))
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34156815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档