【问题标题】:UIBezierPath point at fraction of pathUIBezierPath 指向路径的一部分
【发布时间】:2014-08-02 17:11:08
【问题描述】:

给定一个任意的UIBezierPath,我正在寻找一种方法来在该路径长度的一小部分处获得一个点。

例子:

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(200.0, 200.0)];
[path addLineToPoint:CGPointMake(200.0, 400.0)];

CGPoint p = [path pointAtFraction:0.5];

p 在这种情况下应该是 {x: 200.0, y: 300.0}

我知道这个简单的例子可以计算出来,但我正在寻找适合任何UIBezierPath(弧线、圆角矩形等)的解决方案

看到CAShapeLayer,它基本上以UIBezierPath 为生,它的属性strokeEnd,我想信息在路径对象的某个地方。但是,UIBezierPathCGPathRef 接口都没有显示任何实现此目的的方法。

我尝试创建CAShapeLayer,设置strokeEnd 并从图层中检索CGPathRef,但路径保持不变。

有没有办法(公共 API)来实现这一点?

【问题讨论】:

  • 我认为没有公共 API。您正在寻找的是贝塞尔路径的“弧长参数化”。
  • 嗯,是的。谢谢你的提示。我想那是高等数学......普通软件工程师(我;))是否有可能自己实现这一点,而不会失去理智? :)
  • 这是相关的:stackoverflow.com/questions/12024674/get-cgpath-total-length,因为计算弧长是第一步。
  • 嘿@Cabus,忘记了你在下面承诺的详细答案:)你能分享一下解决方案吗?我需要完全一样的。谢谢!
  • 抱歉耽搁了。我发布了答案;)

标签: ios objective-c uibezierpath quartz-core


【解决方案1】:

前段时间我做了一个基于贝塞尔三次曲线的轮播菜单。我认为这段代码可以帮助你:

CGFloat bezierInterpolation(CGFloat t, CGFloat a, CGFloat b, CGFloat c, CGFloat d) {
    CGFloat t2 = t * t;
    CGFloat t3 = t2 * t;
    return a + (-a * 3 + t * (3 * a - a * t)) * t
           + (3 * b + t * (-6 * b + b * 3 * t)) * t
           + (c * 3 - c * 3 * t) * t2
           + d * t3;
}

- (CGPoint)getPointForT:(CGFloat)t {
    return CGPointMake(bezierInterpolation(t, _p1.x, _p2.x, _p3.x, _p4.x), bezierInterpolation(t, _p1.y, _p2.y, _p3.y, _p4.y));
}

t - 你的分数长度

_p1, _p2, _p3, _p4 - 曲线的点(查看此站点以使其可视化一点:http://cubic-bezier.com/#.17,.67,.83,.67

【讨论】:

  • 是的!非常感谢您提供这段代码!它把我推向了正确的方向;)。 - 老实说,起初我认为代码在我的情况下是无用的,但经过一些研究,我明白为什么它正是这个问题的核心。明天我会发布一个非常详细的答案。我还将“发布”一个类别,这将使这个东西易于使用:)。 - 在我发布我的最终答案之前,我会将你的答案标记为正确答案,因为它为从哪里开始解决这个问题提供了很好的提示。谢谢!
  • 您好,我也遇到了同样的问题,能否分享一下您的解决方案? @Cabus
  • 抱歉耽搁了。我发布了答案;)
  • _p[1-4] 是曲线点,其中 p1 是起点,p2 是终点,3、4 是控制点?还是开始、cp1、cp2、结束?
【解决方案2】:

抱歉,耽搁了这么久。我实际上在一年多前就解决了这个问题,哇。
我在UIBezierPath 上创建了一个小类别来完成这项工作。 GitHub Repo here

在重新阅读我 1 年前的代码后,我不得不说,我当时的编码方式令人震惊:D 缺乏文档令人不安。如果您需要更多信息,请告诉我,我会更新 repo。

【讨论】:

  • 在我回答一年后,您将自己的答案标记为正确,这有点蹩脚,这给了您解决方案。但无论如何;-)
  • 感谢您的回答,感谢您提供如此精彩的类别来支持它!这正是我需要的一半。唯一留给我的是相反的:我想要一个方法- (CGFloat)percentOfPathAtPoint(CGPoint point)。我的数学在这方面太弱了,所以任何指针都将不胜感激......
  • 你给自己的答案正是我要告诉你的 :) 恐怕没有更好的解决方案了:/
猜你喜欢
  • 1970-01-01
  • 2012-02-10
  • 1970-01-01
  • 2016-05-23
  • 1970-01-01
  • 1970-01-01
  • 2011-10-08
  • 1970-01-01
  • 2021-10-01
相关资源
最近更新 更多