2016-02-15

shinyで描画

golangのGUIライブラリはgxuiの開発が止まって以来、
shinyを追いかけている。

このライブラリは最近もテキストをパラグラフとして扱うための
仕組みを実装する等、着々と成長しているが、線を引いたり
円を描いたりといった描画ユーティリティは含まれていないので、
image.RGBAに直書きしないといけない。
example/basicはdrawGradient()の中でピクセル毎にRGB値を
セットすることでグラデーションを表現している。

おそらく将来的にはそういったユーティリティも実装されるのだろうが、
現段階でもshinyでの描画を手元で試したい、ということで実装した。
やり方としては、draw2d/draw2dimgを使うという方法もあったのだが、
いかんせん遅い。マウスでグリグリ回転させたりすることは想定していないの
だろうから仕方ないが。

・線分描画
線分描画といえばブレゼンハムのアルゴリズムである。
wikipediaに載っている中では最も高速なアルゴリズムを写経。

・円描画
「ブレゼンハム 円」等でググるといろいろなページがヒットする。
その中から、ブレゼンハムよりももう少し精度よく、かつ速度を犠牲にせずに描画できる
アルゴリズムとして紹介されていたアルゴリズムを、こちらのサイトを参考に実装。

・多角形塗りつぶし
うーん、これが結構厄介だった。
結局、多角形を三角形に分割してそれぞれ塗りつぶす方式にした。
参考はこちらのサイト
ただし、極力intだけで計算するため、線分描画のアルゴリズムを
基本にするように書き換えたので、結構違うものになっている。
本当はsx23の符合判定も最初のfor文に入る前にできるし、
2箇所だけ残った割り算も積和に置き換えられると思う。
次項のアルファブレンディングとの兼ね合いなのだが、対角線が2回描画されるため、
そこだけ色が変わってしまうのが懸念事項である。

・アルファブレンディング
wikipediaのアルファチャンネルの項を参考に。
元々はRGBAが0〜1の範囲で書かれていたのだが、255で割ってなどいられないので、
すべてビットシフトで置き換え。ちょっと不正確だが、まあよいだろう。

できあがりはこんな感じだ。

No comments:

Post a Comment