1

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

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

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

4

1 回答 1

2

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:)首先执行前一点。这应该可以防止由与加入三次贝塞尔曲线相关的错误引起的所有问题。

于 2017-07-05T23:17:19.820 回答