2012-02-13 17 views
5

コアグラフィックスに描かれた3次ベジェ曲線をタッチしてドラッグすることで、再配置して形状を変更したいと考えています。私は基本的な形を描くことができ、私はタッチのドラッグを使用して形状の全体を移動することができますが、これは私ができるようにしたいものではありません。目的Cベジェ曲線再シェイプ

私が望むのは、テーブル上に横たわっている弦のように、ベジエ曲線を移動したり変形したりすることができることです。つまり、ベジェ曲線の一部に触れ、曲線全体の形状を変更する方向に引っ張ります。

誰でもこれを行う方法を知っていますか?どんな助けも大歓迎です。事前

答えて

5

おかげで制御点を描画し、ユーザーがそれらを周りにドラッグすることを可能にする非常に簡単です。残念ながら、カーブはすべてのコントロールポイントを通過しないので、経験値はあなたが示唆しているものとはまったく一致しません。

あなたが提案していることを行うには、まず「ユーザーがカーブに触れていますか?」という質問に答える必要があります。これは、「曲線のある距離内のある点」と同じです。それは簡単な質問ではありませんが、計算することができます。おそらく最も簡単なアプローチは、曲線上のX点を計算するだけです(ここではXは十分に高いため、合理的な精度を得ることができます)。原則として、距離方程式の導関数を取り、それをゼロで解くこともできますが、これには繰り返しが必要です。私の経験では、余分な複雑さに見合った価値がないかもしれないほど速く(iPad 1上でさえ)十分に速く必要な距離を計算することができます。

ユーザーが実際にカーブに触れていることがわかったら、どのコントロールポイントが最も近いかを簡単に把握できます。この時点で難しいことは、それについて何をすべきかを決めることです。いくつかのオプション:

  • 最も近いコントロールポイントをユーザーが移動している方向に移動します。タッチポイントを通過する新しいカーブを見つけるまで、複数の計算を行う必要があります。これは最も簡単なアプローチで、おそらく私が始めるところです。
  • タッチしたポイントで曲線を細分し、新しく作成したエンドポイントを移動することができます。 (これについては、De Casteljau'sアルゴリズムを参照してください)。これは、他のコントロールポイントを調整して一致する勾配を作成しない限り、鋭いコーナーを作成する傾向があります。これにより、より自由度の高い曲線が得られますが、ユーザーが本当に望むものを知ることは非常に難しくなります。また、曲線の数を爆発させないようにするには、ほとんどの場合Ramer-Douglas-Peuckerを適用する必要があります。

私は現在Objective-Cのベジエ曲線問題にかなり興味があります。あなたは興味があるかもしれません。私はfirst post on the subjectです。この分野の私の最初の作品は、iOS:PTLサンプルコードのGitHubにあります。うまくいけば、私は今週もう1つの投稿をします。あなたの特定の問題は面白いので、私はその周りに何ができるのか見てみましょう。

5

ええ、正確にベジェ曲線が必要ですか?または、のパス上でちょうどの滑らかなカーブが必要ですか?必要な振る舞いは、他のカーブタイプ(Cardinal)やCatmull-Romスプラインのようなサブタイプを使用して実装するのが非常に簡単です。

カーディナルスプラインのベジェに対する利点は、スプラインが常に制御点を通過することです。つまり、パスから点を追加、移動、または消去することは他の点に影響を与えず、曲線は依然として良好です。さらに、数学ははるかに簡単です(計算が速い)。

カーディナルスプラインはCoreGraphicsには表示されませんが、多角形で近似した曲線を描くことができます。tステップです。残りの部分(タッチがカーブを越えているかどうかを調べるなど)はRobの答えで説明されていますが、カーブのポリライン近似を使用すると、この作業がほとんど解決されます。タッチポイントまでの距離が最短です。

+0

優れたポインタ。しかし、私はこのようにポリラインを描こうとするのは少し緊張しています。私の経験では、非常に大きなCGPathは描画に非常にコストがかかる傾向があります。しかし、Catmull-RomをBézierに変換することは可能です:http://stackoverflow.com/questions/1030596/drawing-hermite-curves-in-opengl。それは便利なツールになるかもしれません。カーブを分割してそれをキュービックに単純化する複雑さを残していますが、優れた出発点です。 –

+0

私はプロセス(更新、描画)を最適化するためにいくつかのセグメントにパスを分割していましたが、さらに1つのトリックがあります:tパラメータのステップは可変である可能性があります。カーブセグメントの長さを確認してtを調整することができます。したがって、近点には「スムージング線」はほとんどなく、遠点には十数点の近似線があります。 – Gobra

+0

真。私のリンクされたコードには、「パスに沿って与えられた距離に対して 'tを与えてください」という意味が含まれているので、決して短すぎる行を描かないようにすることができます(間違いなく1px未満にすることはできません。 「t」線形)。私の重大なパフォーマンスの問題は、4000-5000の線分の近傍で起こりました。 –

関連する問題