1

Catmull-Rom splinesを使用して滑らかにした自由形式の落書きを描画するテスト プログラムに取り組んでいます。(リンク) Catmull-Rom スプラインを使用して滑らかな曲線を描く方法を示す「レシピ」については、Erica Sadun の優れた Core iOS Developer's Cookbookを参照してください。(開示: 私はサドゥン博士のいくつかの本の技術評論家でした。)

Objective-C で記述された Dr. Sadun のサンプル コードは、ユーザーが指をなぞると入力ポイント間に一連の線分を描画し、指を離したときにのみ曲線を滑らかにします。

Swift 3 でコードをリファクタリングしました。

また、アルゴリズムを変更して、ユーザーが描いたときに「ライブ」で滑らかな曲線を生成するようにしました。平滑化アルゴリズムの出力は、滑らかな曲線の外観を作成するために小さな線分で接続する必要がある一連の点です。

結果の「ポリライン」を UIBezierPath に変換し、それをカスタム UIView サブクラスの drawRect メソッドで描画します。

滑らかな曲線を作成する計算は、実際には非常に高速であることがわかりました。時間がかかるのは、大きくて複雑なUIBezierPath. 平滑化される入力ポイントの配列に新しいポイントを追加すると、曲線の最後の部分を変更して、「ねじれ」ではなく、前の制御点の周りに滑らかな曲線を作成する必要があります。

結果として、DrawRect を呼び出すたびにベジエ パス全体を描画するのが最も簡単な方法です。ただし、ベジエ パス オブジェクトが大きくなるにつれて、アプリはより多くの時間をサービスに費やすdrawRect()ため、ユーザーの指のパスのトレースがますます遅くなり、ユーザーの動きから登録するポイントがますます離れていきます。

いくつかの最適化を実装しました。setNeedsDisplayInRect()それらの 1 つは、 (むしろ、これは Swift 3 であるため)を呼び出しsetNeedsDisplay(_:)て、実際に変更されたビューの小さな部分のみを再描画する必要があるとしてマークすることです。

私のdrawRect()(er,draw(_:)関数が非常に高速になり、もはや動きがとまらなくなったことに驚きました。

UIBezierPathビューの「ダーティ領域」(実際に更新が必要なクリップ領域) の外側にあるパスの部分をスキップするように、 drawRect()でのオブジェクトのレンダリングが最適化されているようです。

それは私を驚かせました。描画を放棄しUIBezierPath、現在のクリップ領域と交差する描画の部分を見つけるカスタム コードを作成する必要があると予想していましたが、そうする必要はないようです。

現在のクリッピング マスクと交差するパスの部分のみを効率的にレンダリングするように、Quartz の描画がビューの drawrect() メソッド内の UIBezierPaths の描画を最適化することを確認できますか?

4

0 に答える 0