根据绿色对蓝色和红色的数量计算值

时间:2017-03-29 01:02:45

标签: actionscript-3 math colors probability

有点卡在这个上。

这是我的困境:

颜色有3个元素:红色,绿色和蓝色(RGB)。

所有颜色的值均为0-255。

例如:

//
// Get char string/CString from CEdit m_ceDate;
// where
// DDX_Control(pDX, IDC_EDIT_DATE, m_ceDate);

char cdateBuf[128];
UINT nCountOfCharacters = GetDlgItemText(IDC_EDIT_DATE, cdateBuf, 16);
CString csDate = cdateBuf; 

我的评分系统的工作方式是颜色越绿,得分就越高。

这样:

var red:int = 53; 
var green:int = 150;
var blue:int = 28;

将获得最高分(10分)和:

var red:int = 0; 
var green:int = 255;
var blue:int = 0;

将获得最低分(0)。

我需要制作某种方程式。 Bayes' Theorum我应该在哪里吗?

真的没有线索。

6 个答案:

答案 0 :(得分:2)

您的问题是选择(r,g,b)的正确函数,该函数将返回0到10之间的值。您声明(0,255,0)应返回10.0,而其他值应返回较少,(255,0,255)应返回0.因此,您需要为该函数选择至少两个参数。一个是(x,x,x)的值(如果你希望一个是相等的,或者参数是X的函数),另一个是非极值的插值规则。所以,你的函数应该是这样的:

function score(r,g,b:int):Number {
    var rc:int=Math.max(0,Math.min(255,r)); // clamp
    var gc:int=Math.max(0,Math.min(255,g));
    var bc:int=Math.max(0,Math.min(255,b));
    const GRAY:Number=5.0; // value at (x,x,x)
    if ((rc==rg) and (rc==rb)) return GRAY;
    return ir(r,g,b); // interpolation rule
}

事实上,您可以在所有8个角上指定值,并通过您可以想象的任何法则对它们进行简单插值。例如,通过相对距离。像这样:

const SCORES:Array=[
    0, // black, (0,0,0)
    0, // red, (255,0,0)
    10, // green, (0,255,0)
    6.66666, // yellow, (255,255,0)
    0, // blue, (0,0,255)
    0, // magenta, (255,0,255)
    6.66666, // cyan, (0,255,255)
    5.0 // white, (255,255,255)
];
const POINTS:Array=[
    {r:0;g:0;b:0},
    {r:255;g:0;b:0},
    {r:0;g:255;b:0},
    {r:255;g:255;b:0},
    {r:0;g:0;b:255},
    {r:255;g:0;b:255},
    {r:0;g:255;b:255},
    {r:255;g:255;b:255}
]; // respective points

function score(r,g,b:int):Number {
    var rc:int=Math.max(0,Math.min(255,r)); // clamp
    var gc:int=Math.max(0,Math.min(255,g));
    var bc:int=Math.max(0,Math.min(255,b));
    var dists:Array=new Array();
    var td:Number=0;
    for (var i:int=POINTS.length-1;i>=0;i--) 
        var dist:Number=distance({r=rc;g=gc;b=bc},POINTS[i]); // TODO
        if (dist<1e-6) return SCORES[i]; // we're at the corner
        dists.unshift(1.0/dist);
        td+=1.0/dist;
    }
    var result:Number=0;
    for (i=POINTS.length-1;i>=0;i--) 
        result+=SCORES[i]*dists[i]/td;
    return result;
}

答案 1 :(得分:1)

如果仅检查颜色值以从0 - 10范围中提取分数0 - 255,则只需执行以下操作:

score = Math.round( (green / 255 ) * 10 );

所以有了这个逻辑,我们可以看到:

  

green = 253得分为10
green = 190得分为7
green = 128   得分为5
绿色= 47得分为2

有一个阈值,如果数字高于 X 但小于 Y ,它将给出相同的分数,例如243到255之间的任何green将给出得分为10.

PS:一些可测试的代码:

var score:int = 0;
var green:int = 128; //#change this for testing
score = Math.round( (green / 255 ) * 10 );

trace ("score is : " + score);

答案 2 :(得分:1)

这有点棘手,因为有3个组件,但如果我理解正确,只有其中一个组件决定了你的排名。

你可以完全忽略红色和蓝色组件,排名只有0-255绿色等级;结果将是两种颜色的绿色= 64但红色和蓝色的交换值,例如rgb [100,64,50]和rgb [50,64,100]将得到相同的得分,因为两者具有相同的绿色量。这个结果意味着绿色得分是3D RGB坐标到'绿轴'的投影。

答案 3 :(得分:1)

不幸的是,我没有在Action脚本上做,所以可以提供真正的代码,但我想我有一些可能对你有帮助的想法。 AFAIU你的问题是你要衡量&#34; greenishess&#34;考虑到所有3个组件的给定RGB颜色,

  • 绿色将获得100%raiting
  • 红色或蓝色或品红色将获得0%
  • 白色(所有3个中的相等混合物)会在中间得到一些东西

如果我需要设计这样的方案,我会从RGB切换到某种不同的着色方案,例如YUV或更确切地说HSL/HSV。实际上&#34; H&#34;组件aka Hue似乎是你需要的。对维基的评价

  

Hue 是颜色的主要属性(称为颜色外观参数)之一,在技术上定义(在CIECAM02模型中),&#34;可以描述刺激的程度与被描述为红色,绿色,蓝色和黄色的刺激类似或不同的#34;

要计算Hue,首先需要确定最大和最小分量以及它们之间的差异:

 M = max(R, G, B) 
 m = min(R, G, B) 
 C = M - m

然后

If Red is the Max, then Hue = (G - B)/C
If Green is the Max, then Hue = 2.0 + (B - R)/C
If Blue is the Max, then Hue = 4.0 + (R - G)/C

这会产生[-1,5]范围内的值。您可以将它转换为更常规的度数乘以60并将arround包装到fir [0,360],但这并不重要,因为这只是一个线性比例。因此,使用之前定义的Hue计算,您可以衡量&#34; greenishess&#34; Hue值接近2(或以度为120)的颜色。

请注意,从这个公式&#34; greenishess&#34;对于接近绿色的颜色(即绿色为最大分量的颜色)计算为

"greenishess" = abs(B - R)/(G - min(B,R))

这对我有意义。 B = R的部分指定颜色的饱和度,并且只有&#34;多余的&#34; R或B相对于另一个转移了#34;纯粹的#34;绿色到黄色或蓝色。

另请注意,您必须分配一些任意的&#34; greenishess&#34;对所有人的价值&#34;灰色&#34;从{到黑色到白色的颜色C为0,你不能除以0。

最后,您不必直接使用Hue。您可以基于它构建更复杂的公式。例如,您可以设置一些截止点,将0%的等级分配给纯红色和蓝色,即超出[0; 4]范围(或[0; 240]度)。默认情况下,Hue仅将0%分配给Magenta,即{Red = 255,Green = 0,Blue = 255}。像

这样的东西
"greenishness" = [2 - abs(min(4, max(0, Hue)) - 2)] / 2 * 100%

你也可以&#34;曲线&#34;通过应用一些非线性变换进行测量。

答案 4 :(得分:1)

您没有指定您想要此等式的内容。我相信已经说过你有3个参数的功能,但你只给出了两个单个参数的预期输出,并且有许多功能可以满足你的期望,但是这两个输出之间的工作完全不同。

我不知道如果您注意到这一点,但例如colorFitness50 0x000000得分,那么您的期望是什么?

对于你问题的当前状态,我也可以提出这样的建议。

function score(c:uint) {
    var g:uint = (c >>> 8) & 0xFF;
    var s:uint = g + (c >>> 16 & g ^ g);
    s = (s + (c & 0xFF & g ^ g)) / 0x2FD * 100;
    trace("score for", c.toString(16), ":", s);
}

score(0x00FF00); //100
score(0x000000); //0
score(0xFF00FF); //0
score(0xFF7FFF); //16
score(0xFFFFFF); //33
score(0x00FFFF); //66
score(0xFFFF00); //66
score(0x7FFF7F); //66

但是,如果你告诉我们你需要什么样的公式,或者更准确地说明它应该做什么,那就太好了。

答案 5 :(得分:0)

我找到了正确的方法。

请查看以下代码:

var color = parseInt(colorString);
var fitness:Number = 0;
var red:int = (color>> 16) & 0xFF;
var green:int = (color>> 8) & 0xFF;
var blue:int = color & 0xFF;
var greenPercentage = (green/255)*100;
var redAndBluePercentage = ((red+blue)/510)*100;
fitness = greenPercentage-redAndBluePercentage;
fitness = (fitness+100)/2;
trace(fitness);

数学的作用如下: 把你的颜色分成红色,绿色和蓝色。

获取颜色中绿色的百分比。 (X / 255)

取颜色中的红色和蓝色百分比(x / 510)

从绿色中减去红色和蓝色百分比。

为它添加一些数学,为你提供0-100的分数。

colorFitness("0xFF00FF"); //Outputs 0
colorFitness("0x00FF00"); //Outputs 100