2018年3月23日金曜日

cairo_arc_to() #1

以前、Borland C++ Builderで作ったコンタープロットのプログラムがある。先日、NASを整理している時に発掘した。
ひさしぶりにいじろうと思ったが、ウチにはBuilderどころかWindowsも無い。
というわけで、g++ & gtk+ に移植しようと思ったが、gtk+は2010年頃に少し勉強してほったらかしにしていた。
その当時購入した本を本棚から発掘して見てみると、メモが細かく書いてある。何でもかんでも興味本位で手を出すが、やり過ぎて頭の中がごちゃごちゃに混乱し、1ヶ月もすると忘れてしまう。いや、忘れているわけではなく、ぐちゃぐちゃになってしまって、正しい物が何かわからなくなるのだ。
どっちにしても、もう一度勉強し直す必要があるのだが、体の中には概念が残っているし、勉強していた時のメモがあれば、頭にすっと入ってくる。
思い出した事で、思い出しやすくなるというのもあるかもしれないが、記憶もしっかりしてくるような気がする。

gtk+は、cairoでベクタグラフィックを扱うことができる。
この辺は2010年頃には全く勉強していなかった部分だ。コンター図を書くのに使ってみようと思い調べ始めた。
自家製コンタープロットでは、直線しか使っていない。そのため直線と多角形だけ調べれば良いのだが、ついでなので円弧やベジエ曲線についても調べ始めた。

これが脱線の始まりだった。

円弧はcairo_arc()で描画するのだが、これは時計方向しか円弧を描けない。
そのため、多角形の一部に凸向きの円弧と凹向きの円弧を同時に含むことができないと思った。
(この時点ではcairo_arc_negative()を知らなかった) しかし、ベジエ曲線が使えるのだから、円弧をベジエ曲線で表現すればいいと思った。
そもそも円弧はROM-BASICの頃から反比例補完などで表現されきた。それらと同じことだ。
そうと決まれば善は急げで、いろいろ調べた。良い記事を見つけた。

ベジェ曲線の円の近似で90度以外でもよいが180度以上はよくない

上記ページの中ほどに、任意の角度の円弧をベジエ曲線で表現する(誤差はあるが)時の制御点の距離を求める式がある。
k=3/4 tan(θ/4) がそれだ。自分で計算しようとして行き詰まっていたので助かった。

これを利用して、今日の午前中 cairo_arc_to()のような関数を作った。
cairo_line_to()のように終点を指定して円弧を書くのだが、円弧のためには中心と円弧の向き(右回り/左回り)も指定する。
また、90度以上の円弧をベジエ曲線で表現すると誤差が大きくなるようなので、90度以上の場合いくつかのベジエ曲線に分割するようにもした。

簡単な動作確認をして満足したところで、「このような機能は誰でも欲しくなるよな。同じように誰か作っているんじゃない?」と思って、探したら発見した。

[cairo] arc_to again

私が実装したものと多少違っているがやはり存在しているようだ。
さらに、cairo_arc_negative()を発見した。これを使って逆向きに円弧を書くことができるだろう。逆向きにも円弧が書ければ、凹凸両方の円弧を持つパスをつなぐことができる。

またまた無駄なプログラムを書いてしまった。いろいろ勉強になったから良いか。

いつも脱線して、脇道にどんどん入っていくので、頭の混乱につながっていく。
とはいえ、やりかかったのだから、最後までやろう。
もう少し細かい動作確認と、Brush upをしておこう。

つづき。
cairo_arc_to() #2

0 件のコメント:

コメントを投稿