有点卡在这个上。
这是我的困境:
颜色有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我应该在哪里吗?
真的没有线索。
答案 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颜色,
如果我需要设计这样的方案,我会从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个参数的功能,但你只给出了两个单个参数的预期输出,并且有许多功能可以满足你的期望,但是这两个输出之间的工作完全不同。
我不知道如果您注意到这一点,但例如colorFitness
给50
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