JavaでStrokeを変更してお絵かきするとプルプルする現象の対策

大分意味不明なタイトルですが、Javaでお絵かきソフトを作る際に少し躓いたところの対策メモです。

まず、MousePressed メソッドと MouseDragged メソッドに、以下のような絵かき処理のコードを書きました。

マウスがプレスされた瞬間に現在座標を取得し、ドラッグのたびに直線を結び、お絵かきする処理となっています。
ここでは setStroke メソッドを用いることで、線の太さを 50 としています。

一見特に問題無いように思えますが、これを実行してお絵かきしてみると、次のようになります。

purupuru1

ペン形状が正方形の線をマウスで引くと、角度が少し変化する度に正方形の向きが変化するため、プルプルした変な絵になってしまいます。
なんだか気持ちが悪いので、完全なものではないですが修正していきます。

まず、2点間を直線で結ばず、点の描画を連続で行うと、次のようになります。

purupuru2

これだけでも大分滑らかな曲線になりますが、これではマウスのカーソルを動かすスピードが早くなると、飛び飛びの点になってしまいます。
そもそも、点が飛び飛びになるのを防ぐために2点を結んでいたので、この方法ではいけません。

しかしながら、この滑らかさはなかなか捨てがたいので、2点間の距離が大きく空いたときだけ直線で結び、
そうでない場合は点を描けばいいのではと思い、drawLine を以下のように実装しました。

Math.hypot で2点間の距離を計算し、ある数字以上(ここでは適当に 10 としていますが、これはストロークによって変化させなければいけません)の場合は直線を、そうでない場合は点を描くというようにしています。
実行結果は次のようになります。

purupuru3

完璧とは言い難いですが、大分マシにはなりました。
(ここでは hypot を使っていますが、ここには平方根を求める演算が含まれるため、距離の2乗で比較をしたほうが計算コストが軽くなります。)

また、正方形のペン形状に拘らないのであれば、以下のようにペン形状を円形にすることで、綺麗に曲線を描くことができます。

purupuru4


コメントを残す

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">