2011-02-05 2 views
2

У меня есть следующий список из 10 цветов:Отображать неограниченный диапазон значений до 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 до п. Я хотел бы сопоставить эти значения в равной степени с этими 10 цветами, так что наименьшее значение будет первым цветом, а максимальное значение будет сопоставлено с последним цветом. Все остальные цвета должны охватывать равное расстояние в диапазоне значений.

Как это сделать?

Я думаю, что это будет возможно сделать это:

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

Но я не уверен, если это верно для всех возможностей, и если не существует более простое решение.

+0

Не можете ли вы использовать индекс-1? извините, я, наверное, не совсем понимаю. –

+0

да для доступа к списку, но мне нужно рассчитать индекс. –

+0

Если вы имеете в виду реализацию градиента, вы можете посмотреть здесь: http://stackoverflow.com/questions/986352/how-to-do-that-gradient-color-generator –

ответ

4

значения Отображения может быть выражены с линейной функцией: Р (х) = ах + Ь

Оба ваши диапазоны предоставляют точки на этой функции, из которых она может быть рассчитана.
f (1) = 0
f (n) = 9 | Самый высокий индекс в списке из десяти цветов.

0 = а * 1 + Ь
9 = а * п + б

9 = А * (п - 1)
а = 9/(п - 1)
=> Ь = -9/(п - 1)

=> е (х) = 9/(п - 1) * (х - 1)

проблема здесь состоит в том, что если вы округлить, что сразу же меньше значения будут отображаться в 0 и 9, потому что диапазон округления составляет всего 0,5 (от 0 до 0,5 и от 8,5 до 9), поэтому вы можете растянуть диапазон и сдвинуть его обратно на 0,5 на accoun t для этого.

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; 
} 
+0

Спасибо. Это работает для меня. Теперь я столкнулся с другой проблемой. Я один пример, у меня диапазон от 0 до 1116. Однако большинство значений или от 0 до 50 или, может быть, 0 и 100. Таким образом, тем не менее, большинство значений сопоставляются с одним и тем же цветом. Как я могу избежать того, что такие выбросы влияют на мое сопоставление? – RoflcoptrException

+0

Уравнение для диапазонов ввода от 1 до n, как вы указали в своем вопросе, если ваш диапазон теперь начинается с 0, что приведет к неточностям. Кроме того, существует погрешность базы от округления. Я пробовал сопоставлять диапазон от 1 до 1116, и для разных индексов существует разница только в одном значении в длине полосы, поэтому нет большой дивергенции. –

1

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

Ваше предложенное решение содержит несколько проблем:

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

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

INT позиция = Math.round ((значение - мин)/((макс - мин)/(lineColors.Count - 1.))); lineColors.ElementAt (позиция);

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

+0

Sry, но это не работает для меня с десятичными точками, а также ваши значения вне диапазона. – RoflcoptrException

+0

В каком смысле десятичная точка не работает для вас? Я вижу из ответа Х.Б., что вам может понадобиться бросок в (int) в конце. Я не вижу, как значения могут быть вне пределов досягаемости - если вы введете минимум, вы получите 0; если вы ввели max, вы получите lineColors.Count - 1 - пожалуйста, дайте пример, где значения находятся за пределами допустимого диапазона. – joriki

Смежные вопросы