Javascript:将HSV转换为RGB,输出正确但混乱



我使用维基百科上的公式构建了一个将RGB转换为HSV的函数。虽然输出中的数字看起来是正确的,但它们的位置会随着哪个更大而不断变化。

示例:

Given HSV: [204, 100,  94]
Expected RGB: [  0, 144, 240]
Output RGB: [240,   0, 144]
Given HSV: [240, 100,  94]
Expected RGB: [  0,   0, 240]
Output RGB: [240,   0,   0]
Given HSV: [120, 100,  94]
Expected RGB: [  0, 240,   0]
Output RGB: [240,   0,   0]

这个是唯一正确的,因为红色恰好是最大的数字:

Given HSV: [  0, 100,  94]
Expected RGB: [240,   0,   0]
Output RGB: [240,   0,   0]

功能如下:

function hsvRGB(h, s, v) {
h /= 60, s /= 100, v /= 100;    // Convert [deg, %, %] to ranges 0-6, 0-1, 0-1
var r, g, b;                    // Set up for later
var r1, g1, b1;                 // Set up for later
var c = v*s;                    // Chroma
var x = c*(1-Math.abs(h%2-1));
if ( h <= 0 )       [r1, g1, b1] = [0, 0, 0];
if ( 0 <= h <= 1 )  [r1, g1, b1] = [c, x, 0];
if ( 1 < h <= 2 )   [r1, g1, b1] = [x, c, 0];
if ( 2 < h <= 3 )   [r1, g1, b1] = [0, c, x];
if ( 3 < h <= 4 )   [r1, g1, b1] = [0, x, c];
if ( 4 < h <= 5 )   [r1, g1, b1] = [x, 0, c];
if ( 5 < h <= 6 )   [r1, g1, b1] = [c, 0, x];
var m = v-c;
[r, g, b] = [r1 + m, g1 + m, b1 + m];
return [r*255, g*255, b*255];   // Output 0-255 instead of 0-1
}

我一直在根据维基百科上的公式检查我的函数,我看不出它有什么作用,但我已经看了很长时间了,我可能只需要第二双眼睛。

首先,最重要的问题是,尽管

if ( 0 <= h <= 1 )

看起来很合理,但它并不像人们想象的那样起作用。JavaScript将其解释为编写

if ((0 <= h) <= 1)

JavaScript比较运算符返回布尔结果,因此,虽然在语法上是正确的,但它所做的事情与检查h是否在01之间完全不同。

因为该算法使用输入值的H角在六种不同场景中的一种场景之间进行选择,所以整个过程可以用switch语句简单一点(正如在对该问题的评论中所提到的(。首先,编写的代码处理h为负的情况,这很好,但由于它是角度值,因此可以安全地将其强制到[0, 360):范围内

function hsvRGB(h, s, v) {
while (h < 0) h += 360; // could be smarter but just for illustration
h = h % 360;
h /= 60, s /= 100, v /= 100;    // Convert [deg, %, %] to ranges 0-6, 0-1, 0-1

所以现在h06之间;它可能是CCD_ 10,但它永远不会是完全的CCD_。然后我们可以使用switch来区分这些情况:

switch (Math.floor(h)) {
case 0: [r1, g1, b1] = [c, x, 0]; break;
case 1: [r1, g1, b1] = [x, c, 0]; break;
case 2: [r1, g1, b1] = [0, c, x]; break;
case 3: [r1, g1, b1] = [0, x, c]; break;
case 4: [r1, g1, b1] = [x, 0, c]; break;
case 5: [r1, g1, b1] = [c, 0, x]; break;
}

相关内容

  • 没有找到相关文章

最新更新