前提知識
RGB -> HSV 変換式
RGB -> HSV 変換式をベースに、その逆変換を考えていくのがこの記事です。
https://zenn.dev/tetracalibers/articles/78474ee3e8678e
上記の記事と同様に、次の定義を用いる。
const Imax = Math.max(r, g, b)
const Imin = Math.min(r, g, b)
床関数の性質
\lfloor x\rfloorは、xを超えない最大の整数なので、x - 1とxの間の数になります。
x - 1 < \lfloor x \rfloor \leq x
各辺に1を加えると、
x < \lfloor x \rfloor + 1 \leq x + 1
\lfloor x \rfloor \leq xと組み合わせて、
\lfloor x \rfloor \leq x < \lfloor x \rfloor + 1 \leq x + 1
この式から、次の性質を抜き出せます。
\lfloor x\rfloor \leq x<\lfloor x\rfloor +1
事前準備 - 色相を60で割った値の重要性
前記事を見ていただけるとわかるのだが、色相Hの計算式は、いずれも次のような形になっている。
Xは前記事でいう区間内回転率であり、yには0~6の整数が入る。
ゆえに、本記事での計算の過程では、60を括り出す、
のような変形を毎度行うことになり、その流れで\cfrac{H}{60}という形がよく現れることになるので、\cfrac{H}{60}を変数化しておくと式が綺麗にまとまるのだ。
ところで、色相Hは0~360の間の整数ならなんでもありなので、\cfrac{H}{60}は整数になるとは限らない。
\cfrac{H}{60}が整数になるのは、Hが、前記事で規則性が発見された60°ずつの区間の開始角である時のみだ。
つまり、
-
\cfrac{H}{60}の整数部分は、何番目の区間であるかを表す
-
\cfrac{H}{60}の小数部分は、その区間の開始地点からの誤差(その区間内で何%進んでいるか)を表す
ことになる。
これらの重要な値を、まずは変数としてまとめておきたい。
\cfrac{H}{60}の整数部分は、色相の区間を指すindex、みたいな意味合いでH_iとしておく。
H_i = \left\lfloor \cfrac{H}{60} \right\rfloor
\cfrac{H}{60}の小数部分は、小数だからfloatのFにでもしておこうか。
整数部分と小数部分を加えれば元の数値になるので、\cfrac{H}{60} = H_i + Fが成り立つ。
H_i = 0のとき
このとき、色相Hは0°~60°
H_iは何番目の区間かを表す数ということで、H_i = 0は一番最初の区間を表すのだから、Hが0°~60°の範囲であることは至極当然のことである。
と言ってももやもやする人もいるかもしれないので、数学的な証明を書いておく。
H_i = \left\lfloor \cfrac{H}{60} \right\rfloor = 0
床関数の性質より、
0 \leq \cfrac{H}{60} < 0 +1
RGB値の関係性
詳しくは前記事の解説を参照してほしいのだが、以下のような関係にある。
- R = Imax
- G = Imin -> Imax
- B = Imin
明度VからRを求める
明度の定義V = \cfrac{I_{max}}{255}より、
R = I_{max} = 255 \times V
彩度SからBを求める
彩度の定義S = \cfrac{I_{max} - I_{min}}{I_{max}}より、
\begin{align*}
S &= \cfrac{255V - I_{min}}{255V} \\\\
&= \cfrac{255V}{255V} - \cfrac{I_{min}}{255V} \\\\
&= 1 - \cfrac{I_{min}}{255V} \\\\
S + \cfrac{I_{min}}{255V} &= 1 \\\\
\cfrac{I_{min}}{255V} &= 1 - S \\\\
I_{min} &= 255V \times (1 - S)
\end{align*}
BがIminであるから、
B = I_{min} = 255 \times V \cdot (1 - S)
色相HからGを求める
H = 60 \times \cfrac{G - B}{I_{max} - I_{min}}より、
\begin{align*}
H &= 60 \times \cfrac{G - 255V \cdot (1 - S)}{255V - 255V \cdot (1 - S)} \\\\
&= 60 \times \cfrac{255V \cdot \left(\cfrac{G}{255V} - (1 - S)\right)}{255V \cdot (1 - (1 - S))} \\\\
&= 60 \times \cfrac{\cfrac{G}{255V} - (1 - S)}{S} \\\\
\cfrac{H}{60} &= \cfrac{\cfrac{G}{255V} - (1 - S)}{S} \\\\
\cfrac{H}{60} \cdot S &= \cfrac{G}{255V} - (1 - S) \\\\
\cfrac{G}{255V} &= \cfrac{H}{60} \cdot S + (1 - S) \\\\
G &= 255V \cdot \left(\cfrac{H}{60} \cdot S + (1 - S)\right) \\\\
&= 255V \cdot \left(1 + \cfrac{H}{60} \cdot S - S \right) \\\\
&= 255 \times V \cdot \left(1 - S \cdot \left(1 - \cfrac{H}{60} \right)\right)
\end{align*}
ところで、今はH_i = 0なので、
\begin{align*}
\cfrac{H}{60} &= H_i + F \\\\
&= F
\end{align*}
というわけで、代入すると、
G = 255 \times V \cdot \left(1 - S \cdot \left(1 - F \right)\right)
つまり、Hが0°~60°の時のRGB値は、
\begin{cases}
R &= 255 \times V \\
G &= 255 \times V \cdot \left(1 - S \cdot \left(1 - F \right)\right) \\
B &= 255 \times V \cdot (1 - S)
\end{cases}
Unfinished Tasks
近々続き書くよ。KaTeX疲れたにゃん
参考にしたサイト
床関数、整数部分・小数部分
https://www.clearnotebooks.com/ja/notebooks/1196929
https://ja.wikipedia.org/wiki/床関数と天井関数
色の変換原理
https://www.rapidtables.org/ja/convert/color/hsv-to-rgb.html
https://hooktail.org/computer/index.php?RGB����HSV�ؤ��Ѵ�������
Discussion