2017-07-05 3 views
1

私はユーザーが何かを描くことができる私のアプリにセクションを持っています。 touchesMovedのリフレッシュレートが遅いため、ユーザーが速く描画すると線が滑らかにならない。 そのため、私はエルミートを使用しています。すべてのリフレッシュレートのポイントを設定し、それらのポイント間のUIBezierpath(スムーズにするための拡張子付き)を描画します。 これは完璧に機能しています!私は今、滑らかなデザインをしています!swift:エルミートラウンドキャップUIBezierpath

唯一の問題は、時々ラウンドの開始キャップが得られないことです。また、同じパスに戻っても同じことが起こります。

私は、これらの点の間にベジェのパスを描くコードと関係があると思います。だから私はエルミートを使って、これを修正する方法を知っている人を探しています。 enter image description here

+0

関連していませんが、「touchesMoved'の遅いリフレッシュレートのために...」と言います。物理デバイスでは、合体タッチを使用してポイント間のギャップを減らすことができます。これはデバイスでのみ機能し、すべての場合ではありませんが、対応デバイスではより正確なパスになります。あなたはすでにそれをやっているでしょうが、将来の読者のために言及します。 – Rob

答えて

1

hermiteスプラインは単なる一連の立方体ベジエです。しかし、これらの奇妙な矛盾をUIBezierPathで得ることができます。たとえば、開始点、制御点1、制御点2、および終了点がすべて同一直線上にある複数の立方体ベジエを追加すると、レンダリングに問題が発生します(UIBezierPath)。そこで、私はhermiteスプラインパスにチェックを入れて、これら4つの点が同一線上にあるかどうかを確認し、そうであれば、その場合に線を追加します。だから、

、代わりにちょうど:

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) 
} 

別の、より一般的な解決策(ビット洗練しかし、私見)、アプローチは、これらのcuに参加することを避けることですそれぞれの3次曲線を追加する前に、前の点を最初にmove(to:)にします。キュービックベジエを結合することに関連するバグに起因するすべての問題を防ぐことができます。

+0

こんにちは、私はこれを試みましたが、私はまだまったく同じ問題を抱えています。 – MaximVW

+0

パスにカーブを追加する前に 'move(to:previousPoint)'を挿入するなど、連続していないパスを1つ連続しないようにしてください。 。 – Rob

+0

それはトリックをしました、ありがとう! – MaximVW