HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2006
1012
セントラルHSVへの変換について5解決


セントラル

リンク

2006/10/12(Thu) 22:34:57|NO.2954

RGBをHSVに変換する方法を探してみると、

#define _PI 96.0 #define _2PI 192.0 #defcfunc max int p1, int p2 if p1 < p2 : return p2 return p1 #defcfunc min int p1, int p2 if p1 < p2 : return p1 return p2 #deffunc toHSV var H, var S, var V, int R, int G, int B V = max(max(R, G), B) u = min(min(R, G), B) if V { S = 255.0 * (V - u) / V } else { S = 0.0 } if V == R { H = _PI / 3 * (G - B) / (V - u); _PI/3 = 32 } else : if V == G { H = _PI / 3 * (2.0 + double(B - R) / (V - u)) } else { H = _PI / 3 * (4.0 + double(R - G) / (V - u) ) } if H < 0.0 : H + _2PI return
このようなものがありましたが、このスクリプトだと
無彩色(R,G,Bが同じ)だと、
(V - u)は0のため、0で除算したとエラーになってしまいます。
無彩色はV値だけで決まるらしいですが、

if V { S = 255.0 * (V - u) / V } else { S = 0.0 }
この所でVが0(つまり、R,G,Bが全て0)の処理をしているにもかかわらず、
Vが0の場合は

if V == R { H = _PI / 3 * (G - B) / (V - u); _PI/3 = 32 }
この部分でV == Rとなり、
(G - B) / (V - u)の部分で必ずエラーになります。
これを無彩色でも使えるようにしたいのですが、どうすればいいでしょうか。
僕の頭では、いろいろ考えても分かりませんでした。



この記事に返信する


Shinya

リンク

2006/10/13(Fri) 18:27:56|NO.2959

 以前に「HSVへの変換について」で書き込みさせていただいた者です。(NO.2670,2671)
動作を確認せず書き込んでしまいました。すみません。
 以下のサンプルが修正後のものです。
// 整数値比較マクロ
#define global ctype imax(%1, %2) ((%1>=%2)*%1 | %2*(%1<=%2)) #define global ctype imin(%1, %2) ((%1<=%2)*%1 | %2*(%1>=%2)) #module #deffunc toHSV var H, var S, var V, int R, int G, int B V = imax(imax(R, G), B) u = V - imin(imin(R, G), B) ; ↓黒色のときはS,H共に 0 に初期化 if V : S = int(255.0 * u / V) : else : lpoke S : lpoke H : return if V == R { H = int(32.0 * (G - B) / u) } else : if V == G { H = int(32.0 * (2.0 + double(B - R) / u)) } else { H = int(32.0 * (4.0 + double(R - G) / u)) } if H < 0 : H + 192 return #global randomize repeat 10 r = rnd(256) : g = rnd(256) : b = rnd(256) if cnt == 0 : r=0:g=0:b=0 color r, g, b : boxf , , 320, 240 toHSV h, s, v, r, g, b hsvcolor h, s, v : boxf 320, 240 wait 50 loop



セントラル

リンク

2006/10/14(Sat) 11:50:21|NO.2972

ありがとうございます。
しかし、
黒の場合はOKですが、r,g,bが1以上の無彩色だと、
やっぱりエラーになってしまうようです。(uが0になるので)
どうすればいいでしょうか…
度々すみません。



Shinya

リンク

2006/10/14(Sat) 17:28:18|NO.2976

 RGBが同じ値(max == min) のときにはつねに灰色(彩度(S)==鮮やかさが 0)で、
色相(H)に何を指定しても意味がない。
ということに気づきませんでした。セントラルさん、ご指摘ありがとうございます。
	;                                        ↓黒色のときはS,H共に 0 に初期化
if V : S = int(255.0 * u / V) : else : lpoke S : lpoke H : return
の部分を、
	;           ↓灰色のときはS(鮮やかさが)は0で、Hは指定しても意味がない
if u == 0 : lpoke S : return ; ↓黒色のときはS,H共に 0 に初期化 if V : S = int(255.0 * u / V) : else : lpoke S : lpoke H : return
と書き換えてください。



セントラル

リンク

2006/10/14(Sat) 19:25:14|NO.2981

ありがとうございます!
正しく動かすことができました。
自分で作ることもできないのに愚痴ばっかり言ってすみませんでした。
でも、最後にもう1つだけ愚痴を(笑)。

u == 0でreturnするなら、
そのあとVが0(=黒)のことはありません(と、思います)ので、

; ↓黒色のときはS,H共に 0 に初期化 if V : S = int(255.0 * u / V) : else : lpoke S : lpoke H : return
の部分は

S = int(255.0 * u / V)
と置き換えてもいいと思います。
とりあえず、直しても正しく動きました。
とにかく、いままでありがとうございました。



Shinya

リンク

2006/10/14(Sat) 21:18:22|NO.2982

 お〜。なるほど〜。
>; ↓黒色のときはS,H共に 0 に初期化
>if V : S = int(255.0 * u / V) : else : lpoke S : lpoke H : return
>の部分は
>S = int(255.0 * u / V)
>と置き換えてもいいと思います。

 やはり、じっくり考えてプログラミングをすることが基本で、
もっとも大切だと、改めて感じました。セントラルさんありがとうございます。



ONION software Copyright 1997-2023(c) All rights reserved.