ペイント系アプリによくあるストローク補正(手振れ補正)。
タブレットペンやマウスから入力された座標のほとんどを無視することで手振れを無くし、その上でアプリが座標間を補間する機能。
補間する割合が多ければ多いほど線は滑らかでペンの動き通りにはならない。
要点は2つ。
- どの入力座標を間引き、どれを残すか
- 間引いたあとの座標間をどう補間するか
補間法は工夫の必要がなさそう。
間引いた後の座標を全て通る曲線補間法があればいい。
間引き方法の例…
- 一定間隔でしか座標を受け付けない
前の入力から一定距離離れた座標だけ処理、それ以外は無視。はてなハイクやはてなお絵描きがこれっぽい。 - 一定時間ごとにしか座標を受け付けない
前の入力から一定時間経ったら次の入力を受け付ける。それ以外は無視。SAIがこれっぽい。描画が遅くなるが、見せかけだけのポインターを表示して、ユーザーに遅さを感じさせないようにしている。
セルシスのComicStudioやIllustStudioはどう行っているんだろうか。上記のような補正方法で見せかけの線を描画して、ストロークが終わってから本格的に補正した線を描画しなおしているように見える。MicrosoftのExpressionDesignと似た方法?
1ストローク分ごとに補正しているみたい。補正を遅らせるほど多くのデータを扱えるので、ストロークが終わってから補正をしているんだと思う。ストローク中はユーザーへのフィードバックのために見せかけの線を描画、その線さえも別のアルゴリズムで補正しているみたい。
入力座標の間引き方法は分からないが、鋭角の頂点は残しつつそれ以外の部分は直線に近い形になるみたい。
部分的に補正しても局所的な滑らかさにしかならない。ガタガタ→波線(滑らかなガタガタ)になる程度。
ストロークが終わってから線1本分をまとめて補正、それまでは見せかけの線を表示する方法がいい?
補間は既存の曲線補間法(d:id:pmint:20080222:p1)を使うとして、
ここで考えるのは間引きのアルゴリズム。
- ストロークの始点と終点だけで補間してみる
間にある入力座標が全て補間でまかなえる(補間で生成した座標と同じ座標)なら、それらを削除。始点と終点のみ残す。
補正強度(別途設定)が強いほど「まかなえる」と判定されやすくする(多少離れていても同じ座標とする)。 - 未削除の座標が残っているなら、最も特徴的な座標で切る
新たに2区間(3座標間)できるので、それぞれの区間で前項の処理を行なう。
残っていないなら終わり。 - 以上を繰り返す
特徴的な座標とは…線の向きが大きく変わる座標。鋭角の頂点。
評価方法…入力座標ごとに、(両脇の線分の長さ合計 / 両脇の線分が作る角の角度)を算出。これを特徴の大きさとする。角度が0になる場合は特に大きな値として扱う。特に大きな値同士では長さ計がより大きいほうが上。でも手間を省いて全てを最高順位にしても良さそう。
図。
3.補間でまかなえたら確定。左の線はこれで補正済み。
確定できなかった線を特徴的な点で切ってそれぞれを補間してみる。以降は繰り返し。
4.補間で再現できる線分は確定。残りの線を特徴的な点で切る。
後に残る部分(曲線補間しづらい部分)ほど区間が短くなり、有効な入力座標が増え、補正に制限がかかり、ディテールが残るようになる。
これは入力が増えるたびに線全体が影響を受ける方法なので「後補正」と呼ばれるもの。ストローク入力中に線を確定できないので使用感は気持ち悪くなるものの、描いた後から「この線をもう少し強く補正する」といったことができる。