Сопоставить неограниченный диапазон значений с 10 цветами? - PullRequest
2 голосов
/ 05 февраля 2011

У меня есть следующий список из 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 ]

4 голосов
/ 05 февраля 2011

Значения сопоставления можно выразить линейной функцией: 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)
=> b = -9 / (n - 1)

=> 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 голос
/ 05 февраля 2011

Вы не ввели value, min и max - я предполагаю, что min и max являются минимальным и максимальным, соответственно, диапазоном чисел, которым вы хотите быть в состоянии отобразить (в текстовом описании проблемы это будет означать min = 1 и max = n), а value - это значение, которое вы пытаетесь отобразить.

Предлагаемое решение содержит пару проблем:

а) Вам нужно вычесть min из value тоже.
б) Если эти переменные объявлены как целые числа (что, я думаю, они будут), результаты деления будут усечены.
c) Если value равно max, вы хотите lineColors.Count - 1, а не lineColors.Count.
d) Используя floor, вы вводите асимметрию - диапазон значений отображается на самый низкий цвет, но только max отображается на самый высокий цвет. Кажется, предпочтительнее использовать round вместо того, чтобы обрабатывать оба конца спектра одинаково.

Таким образом, решение будет:

int position = Math.round ((значение - min) / ((max - min) / (lineColors.Count - 1.))); lineColors.ElementAt (положение);

(десятичная точка на «1» заставляет всю арифметику быть плавающей точкой.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...