Tkabber Wiki

Nick coloring
Login

Материал из Tkabber Wiki

Предлагается переделать систему раскраски ников/сообщений.

В настоящее время схема такая:

Идея hypersw:

Идея teo:

[16:55]<kostix> teo: насчёт раскраски ников: если ты не хочешь хранить соответствие цветов никам, то как их вручную редактировать? или мы будем хранить только эти вручную заданные цвета?

[16:55]<teo> kostix: да

[16:56]<teo> там надо просто вынести все обращения к массиву NickColors в отдельную процедуру. которая проверит массив, и если там нет ника, то сгенерирует цвет сама.


В качестве хэш-функций предполагается использовать что-либо из tcllib:

Тесты (Tcl 8.4.9, cksum 1.1.0, sum 1.1.0, Linux 2.6.8, 5996.54 bogomips):

% time { crc::cksum gabbagabbahey! } 10000
67 microseconds per iteration
% time { crc::sum gabbagabbahey! } 10000
41 microseconds per iteration

Использовать, видимо, надо sum, т.к. нас интересует наибольшая скорость вычисления.


Заморочки с RGB vs HLS от hypersw:

раз:

<hypersw> kostix: Алгоритм примерно такой.

nickname-string => hash
hash % 252 => hue
(hue, default-luminosity, default-saturation) => color

<hypersw> kostix:

Color GetNickColor(string sNickName)
{
  byte hue = unchecked((uint)sNickName.GetHashCode()) % 253;
  return HLS2RGB(hue, 80, 252);
}

два:

<hypersw> kostix:

/// <summary>
/// Converts an HLS color to an RGB color and returns three byte components.
/// </summary>
public static void HLStoRGB(UInt16 H, UInt16 L, UInt16 S, out Byte R, out Byte G, out Byte B)
{
 UInt16 Magic1, Magic2; /* calculated magic numbers (really!) */
 if(S == 0)
 {
  /* achromatic case */
  R = G = B = (byte)((L * c_nMaxRGB) / c_nMaxHLS);
  if(H != c_nUndefinedHue)
  {
   /* ERROR */
  }
 }
 else
 {
  /* chromatic case */
  /* set up magic numbers */
  if(L <= (c_nMaxHLS / 2))
   Magic2 = (ushort)((L * (c_nMaxHLS + S) + (c_nMaxHLS / 2)) / c_nMaxHLS);
  else
   Magic2 = (ushort)(L + S - ((L * S) + (c_nMaxHLS / 2)) / c_nMaxHLS);
   Magic1 = (ushort)(2 * L - Magic2);
   /* get RGB, change units from c_nMaxHLS to c_nMaxRGB */
   R = (byte)((HueToRGB(Magic1, Magic2, (ushort)(H + (c_nMaxHLS / 3))) * c_nMaxRGB + (c_nMaxHLS / 2)) / c_nMaxHLS);
   G = (byte)((HueToRGB(Magic1, Magic2, H) * c_nMaxRGB + (c_nMaxHLS / 2)) / c_nMaxHLS);
   B = (byte)((HueToRGB(Magic1, Magic2, (ushort)(H - (c_nMaxHLS / 3))) * c_nMaxRGB + (c_nMaxHLS / 2)) / c_nMaxHLS);
 }
}

три:

<hypersw> kostix: и ещё

/// <summary>
/// Utility routine for HLStoRGB.
/// </summary>
public static UInt16 HueToRGB(UInt16 n1, UInt16 n2, UInt16 hue)
{
 /* range check: note values passed add/subtract thirds of range */
 if(hue < 0)
  hue += c_nMaxHLS;
 if(hue > c_nMaxHLS)
  hue -= c_nMaxHLS;
 /* return r,g, or b value from this tridrant */
 if(hue < (c_nMaxHLS / 6))
  return (ushort)(n1 + (((n2 - n1) * hue + (c_nMaxHLS / 12)) / (c_nMaxHLS / 6)));
 if(hue < (c_nMaxHLS / 2))
  return (n2);
 if(hue < ((c_nMaxHLS * 2) / 3))
  return (ushort)(n1 + (((n2 - n1) * (((c_nMaxHLS * 2) / 3) - hue) + (c_nMaxHLS / 12)) / (c_nMaxHLS / 6)));
 else
  return (n1);
}

Теория от hypersw:

<hypersw> kostix: В системе координат HLS можно сгенерить разные цвета примерно одной яркости, отличающиеся оттенком. В координатах RGB ты это так просто не сделаешь. Хотя попробовать можно — задаёшь 3 или 6 базовых цветов (равномерно отстоящих на цветовом круге), делаешь одномерную координату, по ней определяешь, между какими двумя цветами попала точка, намешиваешь их пропорционально. По сути получится эмуляция HLS, зачем, если всё уже придумано до нас :)

<hypersw> kostix: Если рассмотреть пространство RGB, где R, G, B — три перпендикулярные координатные оси (каждая от 0 до 255), то получится кубик. Цвета с одинаковой яркостью (примерно…) будут сидеть в плоскости, перпендикулярной большой диагонали (0,0,0) — (255,255,255). На этой диагонали — серые цвета, чем дальше от неё, тем сочнее. Таким образом, нас интересует линия, получающаяся при пересечении той плоскостью граней куба.

<hypersw> kostix: в зависимости от точки на большой диагонали, через которую проходит плоскость, наша линия будет либо треугольником, либо шестиугольником. Ну или точкой, на концах :) Пространство HLS делает из этой хрени два конуса, состыкованных основаниями. Ось (линия между вершинами) — бывшая большая диагональ куба, с серыми цветами. На поверхности конуса — самые сочные цвета.


ycbl предлагает: в случае возможности видеть джиды участников (в полуанонимных комнатах для админов и в неанонимных — для всех) генерировать цвета не по никам, а именно по джидам участников. Таким образом, например, некто kostix, любящий переименовываться в кого ни попадя, зимой и летом будет виден одним цветом. Собственно, ничто не мешает также отслеживать переименования участников и пристёгивать старые цвета к новым никам → решение проблемы для анонимных и полуанонимных комнат (для не-админов). Механизм отслеживания можно взять из плагина игноров.

Kostix 03:29, 27 декабря 2006 (MSK) Идея с джидами интересна. Возможно, так и стоит сделать. Отслеживание ников требует более сложных заморочек типа таблицы связей "канонических" ников (на которых считается хэш) с текущими. Это противоречит идее не хранить таблицу отображения ников на их цвета в памяти (см. выше).


ycbl 00:06, 24 марта 2008 (MSK) Ещё одна мысль: если уж переделывать, то стоит учесть разные цветовые схемы и добавить в настройки возможность выбора цветовой гаммы ников. Потому что если у человека установлена тёмная схема, чёрные и синие цвета ников будут практически не видны, как не видны в стандартной схеме разные розовые, бледно-оранжевые и прочие пастельные цвета.