GoogleAnalytics

SyntaxHighlighter

2012年3月6日火曜日

[Glaeja] ♫Tell Your World

というわけで『Glaeja』の「多角形」レイヤーのチュートリアルです。

…フルサイズ版よりGoogleChromeのTVCM版のアレンジのほうが好みw


左図左が「多角形」レイヤー自体の設定、右上が[頂点群][編集 ...]で現れる頂点選択画面、右下が各頂点の設定です。

多角形」レイヤーの描画は、基本的には、「多角形」レイヤー設定の[開始点]から始まって、[頂点群]の各頂点を上のものから順に線で結び、1つの図形を形作るものです。

上記各種設定や[頂点群]に含まれる頂点の数によって、引かれる線や図形が異なったものとなります。

以下では、各種設定や[頂点群]に含まれる頂点の数によってどのような図形が描かれるか、を見ていくことにしましょう。

0.用語の説明

図形の頂点は、「多角形」レイヤー設定の[開始点]と[頂点群]の各頂点からなりますが、以降では全て「頂点」と呼ぶことにします。
多角形」レイヤー設定の[開始点]は「0番目の頂点」、[頂点群]の各頂点は上から「1番目の頂点、2番目の頂点、…」、[頂点群]の最後の頂点を「終点」と呼ぶことにします。

開始点]と[頂点群]の各頂点を足した頂点の数を「全頂点数」とします。つまり、[頂点群]に2つ頂点が含まれている場合には「全頂点数は3」となります。

全ての頂点の座標値は、ウィジェット左上を原点(0, 0)とする座標系で、その単位は[dp.]です。

1.線の太さと色の設定

これらは引かれる線の太さと描かれる図形の色を設定します(下図参照)。


上図は「[端点の形状]が四角、[角を丸める]オフ」の場合です。この場合、端点でない頂点が鋭角であると、上図のように鋭く尖ります("miter"という)。この尖り具合はなす角が鋭角になればなるほど大きくなり、ウィジェット描画領域を超えることすらあります(下図左)。この尖り具合を設定する項目はありませんので、[角を丸める]オプションをオンにするか、下図右のように頂点を増やして対応してください。


「[端点の形状]が丸、[角を丸める]オン」だと以下のようになります。


このとき、図形の頂点において、外側は丸くなるが内側は丸くならないことに注意してください。

ver. 2.9.2 から、[端点の形状]というオプションが追加されました。これにより、多角形外枠線の「折れ曲がり点」と「端点」が厳密に区別されるようになりました。

下図に「[端点の形状]が四角、[角を丸める]オン」と「[端点の形状]が切り落とし、[角を丸める]オン」の2つを示します。
[角を丸める]は外枠線の「折れ曲がり点」にのみ作用し、線の両端点は[端点の形状]によって制御されます。

[端点の形状]に[切り落とし]を選ぶと、[丸][四角]の場合と異なり、開始点・終了点からはみ出さずに線が描かれます。

この[端点の形状]の性質は、[線種]を破線にした場合に特に重要となります。
破線の線部は、その全てが開始点・終了点として扱われるため、[端点の形状]に[丸][四角]を選んだ場合、間隙部分にまで線がはみ出し、結果として間隙が短く描画されることになります(下図参照)。

[塗りの色]は、[頂点群]の頂点数が2つ以上の場合にのみ彩色されます。

2.頂点数と描かれる図形

描かれる図形は頂点数によって異なります。

・頂点数が1つの場合([開始点]のみで[頂点群]がゼロ)

この場合、[開始点]に[線の色]で指定した色で、一辺が[線の太さ]となる正方形を描画します。
※ [角を丸める]オプションがオンであっても正方形が描画されます。これは今後のバージョンアップで円の描画に改められる予定です。


・頂点数が2つの場合([開始点]と[頂点群]に1つだけ頂点を含む)

この場合、[開始点]から[頂点群]の頂点へ1本の直線が引かれます。[頂点群]の[頂点のタイプ]が「Bスプライン制御点」であっても無視されます。

[端点の形状]が四角の場合、下図真ん中のように長方形が傾いたような直線が描かれます。


・頂点数が3つ以上の場合

この場合、0番目の頂点-1番目の頂点ー2番目の頂点ー … ー終点と順に直線(もしくは曲線)で結ばれます。

[自動で閉じる]オプションがオンになっていると、終点ー開始点へ線が描かれます。ただし、終点の[頂点のタイプ]設定によりその描画の挙動が異なります(下図参照)。
  • [自動で閉じる]がオフで、終点が[Bスプライン制御点]なら、図形の「塗り」の形は「終点の1つ前の頂点から開始点へ向けてBスプライン曲線で閉じた」形になるが、その最後の曲線は描画されない

  • [自動で閉じる]がオンで、終点が[Bスプライン制御点]なら、図形の「塗り」の形は「終点の1つ前の頂点から開始点へ向けてBスプライン曲線で閉じた」形になり、その最後の曲線も描画される

また、[角を丸める]オプションがオフの場合、描かれる図形の途中の頂点は、その角が正しく尖りますが、終点ー開始点の閉じた部分が下図左のように正しく尖りません([自動で閉じる]のオン・オフどちらでも起こる)。これは(Android側の)仕様ですので、他頂点と同様に尖らせたい場合には、開始点が、図形の頂点ではない、辺の半ばから始まるように設定してください(下図右)。


描かれる図形が下図のように内側に巻き込むようになっていた場合の「塗り」領域は、下図左のように巻き込んだ部分が塗りつぶされない("Even-Odd"タイプという)のではなく、下図右のように図形の外形をなす線の内側全てが塗りつぶされます("Winding"タイプという)。



※ これはver.2.1.1での仕様です。将来的には変更されるか設定可能になる可能性があります。


3.Bスプライン曲線

ここでは「多角形」レイヤーで曲線を描かせるために用いられる「Bスプライン曲線」について簡単に解説します。
「Bスプライン曲線」は、いくつかの制御点を基に端点を結ぶよう定義された曲線で、TrueTypeフォントの形状記述にも用いられているものです。
『Glaeja』では、2つの端点につき1つの制御点を持つ「2次-Bスプライン曲線」が用いられており、その定義式は端点をP1(x1, y1)P2(x2, y2)、制御点をC(xc, yc)とし、媒介変数を t (0 <= t <= 1)とすると、以下のようになります。
  • x = (1-t)2x1 + 2t(1-t)xc + t2x2
  • y = (1-t)2y1 + 2t(1-t)yc + t2y2
…ま、数式なんざ虚仮脅しですw 上記式で定義される「2次-Bスプライン曲線」の描かれ方を幾何的に見てみましょう。

1.下図のように端点P1(x1, y1)P2(x2, y2)と、制御点C(xc, yc)があるとします。補助線としてP1CとP2Cの2本を引きます。


2.補助線P1CとP2Cの中点を点Q1Q2とし、線分Q1Q2の中点を点P3とする。求める「2次-Bスプライン曲線」は、このP3を通るので点を描画する。

3.線分P1Q1の中点を点Q3線分Q1P3の中点を点Q4とし線分Q3Q4の中点を点P4とする。求める「2次-Bスプライン曲線」は、このP4を通るので点を描画する。

4.同様に、線分P2Q2の中点を点Q5線分Q2P3の中点を点Q6とし線分Q5Q6の中点を点P6とする。求める「2次-Bスプライン曲線」は、このP6を通るので点を描画する。


5.3.4.と同様の操作を点がつながり滑らかな曲線となるまで繰り返したものが、端点P1P2制御点Cで定義される「2次-Bスプライン曲線」となります。


上記手順3.で描かれたP3が、このBスプライン曲線の通る曲線のうちで、端点から最も遠い(制御点に最も近い)点となります。

ではもうちょっと現実的な欲求として、「3つの点P1P2P3を通るBスプライン曲線の制御点Cの座標値(xc, yc)」を求めるにはどうすればイイのでしょうか?これは簡単で、上記手順の2.の逆の作図をすればイイだけですね。

つまり下図のように、点P1P2を繋ぐ線分P1P2の中点を点Q1とし、点Q1から点P3を通る直線を引き、その直線上で点Q1からの長さが線分Q1P3の倍の長さとなる点が制御点Cとなります。


ただ、[端点P1 → 端点P2 → 端点P3]のなす角があまりに鋭角な場合、パッと見た目の「端点から最も遠い点」が端点Pと一致しないことがままありますので注意が必要です(下記4.の一番下の図のような場合)。


4.「多角形」レイヤーにおけるBスプライン曲線

上記3.でBスプライン曲線についてはわかったかと思います。ここでは、『Glaeja』の「多角形」レイヤーに実装されたBスプライン曲線の特徴について記します。

TrueTypeなどで使用されているBスプライン曲線では、その曲線形状を端点と制御点で記述する際に、端点が暗黙的に決定される場合には端点を省略することができる、という仕様があります。つまり「端点と制御点を繋ぎ順の並べた場合、制御点が連続することが許される」ということです。

…どういう意味だってばよwww 図で示すと以下のような感じですかね。


[端点P1 → 制御点C1 → 制御点C2 → 端点P2]と並んでいる場合、制御点C1C2の中点に暗黙的に端点Qが置かれ、「P1 - C1 - Q」と「Q - C2 - P2」という2本のBスプライン曲線が描画される、ということです。(数学的には違うのですが)ちょっと3次のベジェ曲線っぽい記述が可能になるわけですね。

このような「連続した制御点」というのは、処理の都合上『Glaeja』 の「多角形」レイヤーでは許されていません。ですが、「多角形」レイヤーの[頂点群]に含まれる各頂点は、その[頂点のタイプ]を自由に[Bスプライン制御点]に変更することが可能です。そのため、許されていないにもかかわらず「制御点が連続する」という状態にすることができてしまいます。

では、「多角形」レイヤーにおいて「制御点が連続する」ように[頂点群]を設定するとどうなるのでしょう?

それは、「連続した制御点のうち、偶数番目のものは強制的に端点として処理・描画される」ことになります。


多角形」レイヤーで[端点P1 → 制御点C1 → 制御点C2 → 制御点C3 → 端点P2]と制御点を3つ連続させた場合、偶数である2番目の制御点C2が強制的に端点として扱われ、上図のような曲線が描かれます。

多角形」レイヤーでは上図のような場合以外に、「制御点が連続したまま[頂点群]が終わる(つまり最後の頂点が制御点)」だとか、「さらにその連続した制御点が奇数個だった(つまり最後に端点を強いるべき頂点がない)」とか、かなりトリッキーなシチュエーションが考えられます。これらの場合にどのように描画されるかいちいち書きません。興味のある方は是非とも実験してみてください。強制終了はしませんからご安心をw


5.最後に

とりあえず、ここまでで「多角形」レイヤーの解説はお終いです。チュートリアルの最後は、大抵の場合、何か作例を出すんですが、「多角形」レイヤーはぶっちゃけただのお絵描き道具ですので、凝った作例が作りにくいんですよね。

…凝ろうと思えば、「ウィジェット変数と組み合わせて過去何時間かのバッテリー残量をグラフ表示」とかもできるんですけどねw

そこまでやるのは大変ですので、簡単に「みんな大好きな『角丸(英語でいうと"Rounded Rectangle")』の作り方」を書いて終わりにしたいと思います。

1.まずは下絵となる長方形を「多角形」で描きます。ここでは下図のような[(20, 20), (140, 20), (140, 80), (20, 80)]の長方形を描きました。これの4つの頂点を半径20で丸くしてみましょう。


2.この「多角形」レイヤーを複製し、そちらを使って角丸にしていきましょう。
まず、開始点が下絵では長方形の頂点になっていましたが、これを辺の半ばあたりの点に変更します。これは「開始点は必ず端点になる」ので、丸めるところにいないほうが都合がいいからです。

下図のように、開始点を(80, 20)に変更し、[頂点群]に新しい終点(20, 20)を追加します。


3.では右上の角から丸めていきましょう。半径20なので、下図のように丸めた部分の端点となる頂点を2つ(120, 20)、(140, 40)として追加します。


4.そして、もともとの長方形の頂点だった点(140, 20)の[頂点のタイプ]を[Bスプライン制御点]に変更します。すると下図のようにキレイに角が丸くなります。


5.あとは残りの頂点を同様に処理していけばOKです。下図に右下・左下を処理したものを示します。


6.左上は終点ですが、気にせず同じように端点を2つ(20, 40)、(40, 20)と追加をします。2つ目の(40, 20)が新しい終点になります。


6.最後に[自動で閉じる]をオンにすれば完成です。


あとは下絵を削除して、中を塗りつぶすなり、透過させるなり、コロ助なりして楽しんでください。


以上です。

7 件のコメント:

匿名 さんのコメント...

最近glaejaを使い始めた者です。
角丸がどうしても作成できません。
よろしければ、残りの角を丸める設定も記載いただけるとありがたいです。

kanitawa さんのコメント...

                                 、ヽ l / ,
                                =     =
                               ニ= 荒 そ -=
  、、 l | /, ,                           ニ= 巻 れ =ニ
 .ヽ     ´´,                      =-. な で -=
.ヽ し き 荒  ニ.                      ニ   ら も ニ
=  て っ 巻  =ニ                     r  :   ヽ`
ニ  く と な  -=                       ´/小ヽ`
=  れ 何 ら  -=             _,,..,,,,_
ニ  な. も   =ニ     、,  ,,, 、,,  ./ ,' 3/⌒ヽ-、_   、 ,,  @
/,  い     ヽ、         、,   /l.  /____/   n  ヽ|ノ,,
 /     ヽ、    @   ,,, 、,,  ̄,, ̄ ̄ ̄ ̄,, ̄   ,,, 、,,
 / / 小 \       ヽ|ノ 、、,  ,, 、,,   , "  ,,  、、, ,,

……これ以上簡単に説明か…………

kanitawa さんのコメント...

※以下、メモ帳などにコピペして等幅フォントで見てください

例えば、

..10..........70
10┏━━━━━┓
..┃..........┃
..┃..........┃
..┃..........┃
50┗━━━━━┛

こんな四角形を角丸にするには、

..10..........70
10○●━━━●○
..●..........●
..┃..........┃
..●..........●
50○●━━━●○

のように頂点を置く必要があります。

●が端点で、○がBスプライン制御点です。

具体的には、

..10..........70
10⑫①━━━②③
..⑪..........④
..┃..........┃
..⑩..........⑤
50⑨⑧━━━⑦⑥

と各頂点に番号を振り、頂点群を上から














とセットして座標値を設定していき、

③⑥⑨⑫の4点を「Bスプライン制御点」に変更する

とすればできる……はずです。

匿名 さんのコメント...

ですよね…
作例のとおりにやってみたのですが、例より角がだいぶ丸くなってしまい、試行錯誤したのですがうまくできませんでした。
素敵なアプリなので使えるようになりたかったのですが。
無理なようでしたら結構です。
失礼いたしました。

kanitawa さんのコメント...

※これもメモ帳などにコピペして等幅フォントで見てね

角の丸みを減らすなら、

..○───●───……
..│
..│
..│
..●
..│

こんなのを、

..○─●─────……
..│
..●
..│
..│
..│

てな感じで、端点とBスプライン制御点の距離を縮めればよろしいかと。

匿名 さんのコメント...

3の(80,20)(80,20)として追加…の部分がよくわからなかったのですが、コメントのように設定したらできました。
ありがとうございました。

kanitawa さんのコメント...

> 3の(80,20)(80,20)として追加

あ、そこ間違えてましたね……
直しときました、申し訳ないです(ヽ´ω`)