将无限范围的值映射到10种颜色?

时间:2011-02-05 13:39:58

标签: c# .net wpf

我有以下10种颜色的列表:

public static readonly IList<Brush> lineColors = new ReadOnlyCollection<Brush>
        (new List<Brush> { 
            new SolidColorBrush(Color.FromRgb(35, 31, 32)),
            new SolidColorBrush(Color.FromRgb(64, 64, 66)),
            new SolidColorBrush(Color.FromRgb(89, 89, 91)),
            new SolidColorBrush(Color.FromRgb(110, 111, 113)),
            new SolidColorBrush(Color.FromRgb(129, 130, 132)),
            new SolidColorBrush(Color.FromRgb(148, 149, 153)),
            new SolidColorBrush(Color.FromRgb(168, 169, 173)),
            new SolidColorBrush(Color.FromRgb(189, 190, 193)),
            new SolidColorBrush(Color.FromRgb(210, 211, 213)),
            new SolidColorBrush(Color.FromRgb(231, 231, 232))
        });

现在我的范围从1到n。我想将这些值平均映射到这10种颜色,以便最小值是第一种颜色,最高值映射到最后一种颜色。所有其他颜色应在值范围内覆盖相等的距离。

怎么做?

我认为这可能会这样做:

int position = Math.floor( value / ((max - min) / lineColors.Count));
lineColors.ElementAt(position);

但我不确定这是否适用于所有可能性以及是否有更简单的解决方案。

2 个答案:

答案 0 :(得分:4)

映射值可以用线性函数表示:f(x)= ax + b

你的两个范围都提供了可以计算它的函数的点数 f(1)= 0
f(n)= 9 |十种颜色列表中的最高指数。

0 = a * 1 + b
9 = a * n + b

9 = a *(n - 1)
a = 9 /(n - 1)
=&GT; b = -9 /(n - 1)

=&GT; f(x)= 9 /(n - 1)*(x - 1)

这里的问题是,如果你立即将其舍入,则较小的值将映射到0和9,因为舍入范围仅为0.5(从0到0.5和从8.5到9),因此您可以扩展范围和移位为了解释这一点,它回到了0.5。

private int MapValue(int value, int n)
{
    int output = (int)Math.Round((10.0 / (n - 1) * (value - 1)) - 0.5, 0);
    if (output == -1) return 0;
    else return output;
}

答案 1 :(得分:1)

您没有介绍valueminmax - 我假设minmax分别是最小值和最大值,您希望能够映射的数字范围(在您对问题的文本阐述中,这意味着min = 1max = n),并且value是您的值'重新尝试映射。

您建议的解决方案包含几个问题:

a)您也需要从min中减去value b)如果这些变量被声明为整数(我想它们将会是),则除法结果将被截断 c)如果valuemax,则需要lineColors.Count - 1,而不是lineColors.Count
d)通过使用floor,您引入了不对称性 - 一系列值被映射到最低颜色,但只有max被映射到最高颜色。似乎最好使用round来对待光谱的两端相同。

所以解决方案是:

int position = Math.round((value - min)/((max - min)/(lineColors.Count - 1.))); lineColors.ElementAt(位置);

(“1”的小数点强制所有算术都是浮点数。)