フラット表示 投稿するには登録が必要です | 前のスレッド | 次のスレッド |
投稿者 | スレッド |
---|---|
投稿数: 189
|
投稿日時: 2008-07-13 00:56 レインボースクリプト |
別スレで、かなり前に紹介したレインボースクリプト(パート内のオブジェクトの拡散反射色をセットする )の件が出てきました。
その時は単に RGB color での補間で作ったのですが、もっと綺麗な色相グラデーションがセットできるように HSV color で補間する AppleScript を作ってみました。 どうも AppleScript では RGB, HSV 双方向の変換をサポートしてくれる関数が用意されていないようでしたので、この変換ルーチンも書いておきました。 Python だと簡単に RGB, HSV の変換ができるので、もっと簡単に書けますね。 興味のある方はどうぞ Shade 8, 9 で使用する場合は 54行目の set n_Child to (number of sons of active shape 1 of scene 1) を次のように書き換えて下しさい set n_Child to (number of sons of shape 1 of active objects of scene 1) ----- ここからチョッキン ----- tell application "Shade 10" -- 入力ダイアログ - 1 activate begin dialog 10 -- dialog ID には適当な数字を入れてください append int dialog item "指定する色の数(2〜 24 )" if ask dialog then set n_color to (get int property value 0) -- 色を指定するダイアログの数を与えます。 end dialog if n_color < 2 or n_color > 24 then beep return end if else return end if -- 入力ダイアログ - 2 begin dialog 20 -- dialog ID には適当な数字を入れてください set n to n_color - 1 repeat with i from 1 to n -- RGB ダイアログを n_color 個作成 append RGB dialog item (i as text) append bool dialog item "時計回り" end repeat append RGB dialog item (n_color as text) append bool dialog item "黒と黒以外の色との補間において、黒の彩度を0とする" set colorL to {} -- 入力ダイアログで指定される色を格納するリストを空リストとして作成 set clockWiseL to {} -- 入力ダイアログで指定される色相の変化する方向を格納するリストを空リストとして作成 if ask dialog then set k to 0 repeat with i from 1 to n set colorL to colorL & {(get RGB property value k)} -- colorL にユーザーが指定する色を順次格納 set k to k + 1 set clockWiseL to clockWiseL & (get bool property value k) set k to k + 1 end repeat set colorL to colorL & {(get RGB property value k)} -- colorL にユーザーが指定する色を順次格納 set blackSaturation to (get bool property value k + 1) -- 黒の彩度の扱いに関するフラグ( true で彩度=0とし、false で補間相手の色の彩度に合わせる ) set clockWiseL to clockWiseL & true -- これは最後のオブジェクトの色を決定する際に dummy data として必要とされる end dialog else return end if -- 処理 inhibit update if object type = part object then -- 選択オブジェクトがパート(自由曲面やジョイント類を含む)なら set n_Child to (number of sons of active shape 1 of scene 1) -- 選択されているオブジェクトの子の数を調べる if n_Child > 1 then -- 子オブジェクトが2個以上存在する (n_child = 1 だと SetColor() の中でエラーとなってしまう) select child set counter to 1 -- 何番目の子であるかを示すカウンター set base color to my SetColor(n_color, colorL, clockWiseL, n_Child, counter, blackSaturation) -- SetColor() で決定される拡散反射色をセットする repeat (n_Child - 1) times select brother set counter to (counter + 1) -- カウンターを一つ進ませる set base color to my SetColor(n_color, colorL, clockWiseL, n_Child, counter, blackSaturation) end repeat select parent end if end if allow update end tell on SetColor(n_color, colorL, clockWiseL, n_Child, counter, blackSaturation) -- 色を設定する sub-routine -- n_color : 指定された色の数 -- colorL : 指定された色を格納したリスト -- clockWiseL:指定された色相の変化する方向を格納するリスト -- n_child : 子オブジェクトの総数 -- counter : 現在の子の番号(1から始まる) -- blackSaturation:黒の彩度の扱いに関するフラグ( true で彩度=0とし、false で補間相手の色の彩度に合わせる ) set d to (n_color - 1) / (n_Child - 1) set pos to d * (counter - 1) -- 4つの色が指定された場合、子オブジェクトの番号に応じて 0〜3( = 4 - 1) の数字を pos として割り当てる set item_1 to (pos div 1) + 1 -- (pos div 1) で切り捨てとなる、例えば、pos = 0.5 ならば切り捨てられて 0、それに1を加えて結果 item_1 = 1 となる if item_1 ≠ n_color then -- 選択されている子オブジェクトへの色を指定された色の間で定義するが、その際に使用される左側の色番号 set item_2 to (item_1 + 1) -- 選択されている子オブジェクトへの色を指定された色の間で定義するが、その際に使用される右側の色番号 else set item_2 to item_1 end if set pos to (pos - (pos div 1)) -- pos から自身を切り捨てた数値を引く、すなわち pos の小数点以下をあらためて pos として再定義 set color_1 to (item item_1 of colorL) -- 左側の色番号に従って colorL の中から左側の色を取り出す set color_2 to (item item_2 of colorL) -- 右側の色番号に従って colorL の中から右側の色を取り出す set clockWise to (item item_1 of clockWiseL) -- 左側の色番号に従って clockWiseL の中から色相の変化させる方向を取り出す set {red, green, blue} to my MorphingColorHSV(color_1, color_2, clockWise, pos, blackSaturation) -- color_1, color_2 の間で pos を使って中間の色を HSV ベースで補完して求める return {red, green, blue} -- RGB color としてリスト形式で返す end SetColor on MorphingColorHSV(color_1, color_2, clockWise, pos, blackSaturation) -- 色を HSV ベースで補間して求める sub-routine -- color_1, color_2 の間で pos を使って中間の色を HSV ベースで clockWise の方向に従って補間し求める。 0 <= pos <= 1 -- blackSaturation:黒の彩度の扱いに関するフラグ( true で彩度=0とし、false で補間相手の色の彩度に合わせる ) -- {h1, s1, v1}, {h2, s2, v2} : color_1, color_2 を HSV で表記したもの 0 <= hue < 360 -- (h, s, v}:HSV ベースで補完して求められた色 set {h1, s1, v1} to my RGB_to_HSV(color_1) set {h2, s2, v2} to my RGB_to_HSV(color_2) ----- hue ----- if s1 = 0 or v1 = 0 then -- {h1, s1, v1} がグレースケールの場合 set h1 to h2 -- もう一方の hue に合わせる else if s2 = 0 or v2 = 0 then -- {h2, s2, v2} がグレースケールの場合 set h2 to h1 -- もう一方の hue に合わせる end if if not clockWise then -- 色相の補間が反時計回りなら repeat while h1 > h2 set h2 to h2 + 360 end repeat else -- 色相の補完が時計回りなら repeat while h1 < h2 set h2 to h2 - 360 end repeat end if set h to h1 + pos * (h2 - h1) repeat while h < 0 set h to h + 360 end repeat repeat while h ≥ 360 set h to h - 360 end repeat ----- saturation ----- if not blackSaturation then -- 黒の彩度を補間相手の色の彩度に合わせる if v1 = 0 then -- {h1, s1, v1} が黒の場合 set s1 to s2 -- もう一方の saturation に合わせる else if v2 = 0 then -- {h2, s2, v2} が黒の場合 set s2 to s1 -- もう一方の saturation に合わせる end if end if set s to s1 + pos * (s2 - s1) ----- value ----- set v to v1 + pos * (v2 - v1) return HSV_to_RGB({h, s, v}) -- (h, s, v} の RGB を返す end MorphingColorHSV on RGB_to_HSV(c) -- RGB 表記で与えられる c の HSV 表記を求める 0 <= hue < 360, 0 <= s, v <= 1 -- min, max: r, g, b 値の最小値と最大値 -- (h, s, v}:HSV に変換して表記された色 set {r, g, b} to c if r ≥ g and r ≥ b then -- r が一番大きい set max to r if g ≥ b then set min to b else set min to g end if if max ≠ min then set h to 60 * (g - b) / (max - min) else set h to 0 end if else if g ≥ r and g ≥ b then -- g が一番大きい set max to g if r ≥ b then set min to b else set min to r end if if max ≠ min then set h to 60 * (b - r) / (max - min) + 120 else set h to 0 end if else -- b が一番大きい set max to b if r ≥ g then set min to g else set min to r end if if max ≠ min then set h to 60 * (r - g) / (max - min) + 240 else set h to 0 end if end if repeat while h < 0 set h to h + 360 end repeat repeat while h ≥ 360 set h to h - 360 end repeat if max ≠ 0 then set s to (max - min) / max else set s to 0 end if set v to max return {h, s, v} end RGB_to_HSV on HSV_to_RGB({h, s, v}) -- HSV 表記で与えられる {h, s, v} の RGB 表記を求める 0 <= hue < 360, 0 <= s, v <= 1 if s = 0 then return {v, v, v} else set n to round (h / 60) rounding down -- 切り下げ set f to h / 60 - n set p to v * (1 - s) set q to v * (1 - f * s) set t to v * (1 - (1 - f) * s) if n = 0 then return {v, t, p} else if n = 1 then return {q, v, p} else if n = 2 then return {p, v, t} else if n = 3 then return {p, q, v} else if n = 4 then return {t, p, v} else return {v, p, q} end if end if end HSV_to_RGB |
フラット表示 投稿するには登録が必要です | 前のスレッド | 次のスレッド |
題名 | 投稿者 | 日時 |
---|---|---|
» レインボースクリプト | 加藤俊明 | 2008-07-13 00:56 |
Re: レインボースクリプト | 加藤俊明 | 2008-07-13 01:01 |
Re: レインボースクリプト | warp | 2008-07-14 01:16 |
Re: レインボースクリプト | 加藤俊明 | 2008-07-18 20:53 |