ma2のblog - わんくま版(仮)

うどん、より、そば

目次

Blog 利用状況

ニュース

Xbox360ゲーマータグ

リンク

ブログ内検索

書庫

日記カテゴリ

三角関数を使わずに丸を描く方法

Twitterで「三角関数を使わずに円が書ける方法、これってエントリになりませんかね?」みたいな事をつぶやいたら、意外にも反応されてしまいましたorz
てことでネタにします。

roundhilight

以前、Perlin Noiseアルゴリズムでテクスチャを作ったときに、外周を丸くする必要がありました。
そのためには各ピクセルの値にかける係数を用意しなくてはいけません。
アルファ値(透明度)というやつです。

外周を丸くとるということで、処理を施す際に次のような環境と条件が挙げました。

  1. アルファ値の処理は、すべてのピクセルに対して行う
  2. 画像の中心を座標の(0,0)としてする。左上はマイナス方向(-x,-y)。右下はプラス方向(x,y)とする
  3. 画像の中心を1.0として、外周を0.0とする。もしくは、逆の条件の計算を行って変換する
  4. 画像の中心から外周までの距離以上のピクセルのアルファ値は一律0.0とする

と偉そうに書いてみましたが、実際はあれこれいじった末の条件です。

例として、256x256の画像に処理を施すとします。
# ちなみにこのエントリの説明では、正方形の画像にしか適用できません
(2)の条件を当てはめると、画像の四隅と中心は次のように置き換わります。

centerpos

X=128,Y=0(右端中段)やX=0,Y=128(中央下段)の座標での計算結果が0.0もしくは1.0になるような計算をすればいいわけですが・・・そんなものが都合よく・・・ありました。
詳しい説明はスベるので<s>しません</s>できませんが、二乗平均から距離を求めます。

W = 128 ... 画像の幅と高さを1/2した値
WMax = (W ^ 2) = 16384
a = ((X ^ 2) + (Y ^ 2)) / WMax

この式を検算してみます。

X=0,Y=0
a = (0 + 0) / 16384
a = 0.0

X=128,Y=0
a = (16384 + 0) / 16384
a = 1.0

X=0,Y=128
a = (0 + 16384) / 16384
a = 1.0

X=128,Y=128
a = (16384 + 16384) / 16384
a = 2.0

区切りがいい場所の計算結果だけ見ると、当たり前のように見えますが、これを他の座標で計算してみます。

X=64,Y=64
a = (4096 + 4096) / 16384
a = 0.5

X=80,Y=80
a = (6400 + 6400) / 16384
a = 0.78125

aの値を反転させるためには、「1.0 - a」とします。
実際の位置と色を目視で確認してみると、それらしい色になっていると思います。
# 端折っているようですが、ここだけはすみませんorz

また、以上の計算の中にひとつだけ条件4にあてはまるものがあります。
X=128,Y=128,a=2.0の計算です。
条件4は要するに、aが1.0を超えるものは1.0として扱うというものです。
この条件があることで、補正されたaを「1.0 - a」とすると外周が取れて丸くなります。

改めて演算結果だけを検証してみて驚いたことに外周にガタが出ることなく丸くなったことに驚きました。
アルファ値として使うと多少のガタが出ても目立たないので。
ただ、これを何に使うのか。使い道は・・・ゲームのエフェクトとか? ハイライトっぽい光球とか。

最後に、もともとアルファ値として用意したものなので、前回のノイズ以外のものと合成してみました。
不遜じゃけぇのぅ マグさんフィールド
画像は、不遜でおなじみのマグさんを勝手にお借りしました。
# なにか問題があれば差し替えます

投稿日時 : 2008年8月29日 23:44

コメントを追加

# re: 三角関数を使わずに丸を描く方法 2008/08/30 6:27

うわぁ、変な顔・・・ってマグさんwww

># なにか問題があれば差し替えます <問題ないっす、ないっす。

タイトル
名前
URL
コメント