【问题标题】:swift: Hermite round cap UIBezierpathswift: Hermite 圆帽 UIBezierpath
【发布时间】:2017-07-06 16:00:42
【问题描述】:

我的应用中有一个部分,用户可以在其中绘制一些东西。 由于 touchesMoved 的刷新率较慢,如果用户画得很快,线条就不会流畅。 这就是我使用 Hermite 的原因。它为每个刷新率设置一个点,然后在这些点之间绘制一个 UIBezierpath(带有扩展以使其平滑)。 它工作得很好!我现在有一个流畅的设计!

唯一的问题是我有时没有获得回合开始上限,如果我在相同的路径上切换也会发生这种情况。

我认为这与在这些点之间绘制贝塞尔路径的代码有关。所以我正在寻找也使用 Hermite 并且知道如何解决这个问题的人。

【问题讨论】:

  • 无关,但你说“因为touchesMoved...的刷新率慢”。请注意,在物理设备上,您可以使用合并触摸来减少点之间的间隙。它仅适用于设备,即便如此,并非在所有情况下,但对于功能强大的设备,它会产生更准确的路径。您可能已经这样做了,但为了将来的读者,我提到它。

标签: swift uibezierpath hermite


【解决方案1】:

hermite 样条曲线只是一系列三次贝塞尔曲线。但是你可以通过UIBezierPath 得到这些奇怪的差异。例如,当您添加多个三次贝塞尔曲线时,会出现UIBezierPath 渲染问题,其中起点、控制点 1、控制点 2 和终点都共线。因此,我在 Hermite 样条路径中添加了一个检查,以检查这四个点是否共线,如果是,则在这些情况下添加一条线。

所以,不仅仅是:

addCurve(to: endPoint, controlPoint1: control1, controlPoint2: control2)

我愿意:

let angleFull = angle(between: previousPoint, and: endPoint)
let angle1 = angle(between: previousPoint, and: control1)
let angle2 = angle(between: control2, and: endPoint)

if (angleFull == angle1 || angle1 == nil) && (angleFull == angle2 || angle2 == nil) {
    addLine(to: endPoint)
} else {
    addCurve(to: endPoint, controlPoint1: control1, controlPoint2: control2)
}

在哪里

private func angle(between point1: CGPoint, and point2: CGPoint) -> CGFloat? {
    if point1 == point2 { return nil }
    return atan2(point2.y - point1.y, point2.x - point1.x)
}

另一种更通用的解决方案(尽管有点不雅,恕我直言),方法是避免完全连接这些三次曲线,因此,在添加每条三次曲线之前,先执行move(to:) 前一点。这应该可以防止由与加入三次贝塞尔曲线相关的错误引起的所有问题。

【讨论】:

  • 您好,我已经尝试过了,但我仍然遇到完全相同的问题。
  • 尽量不要使它们成为单个连续路径(例如,在向路径添加曲线之前插入 move(to: previousPoint)。这是一种不优雅但更可靠的方法来绕过 UIBezierPath 中的错误,不知道如何加入三次曲线。
猜你喜欢
  • 2016-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多