static Dictionary <int, Color> GetColorSpectrum() { var spectrum = new Dictionary <int, Color>(); int colorIndex = 0; for (int i = 1; i < 360.0 - 1; i++) { Color nextColor = RGBHSL.HSL_to_RGB(new RGBHSL.HSL { H = (i + 1) / 360.0, S = 1, L = 0.5 }); Color previousColor = RGBHSL.HSL_to_RGB(new RGBHSL.HSL { H = i / 360.0, S = 1, L = 0.5 }); colorIndex += PercievedColorDistance(nextColor, previousColor); if (!spectrum.ContainsKey(colorIndex)) { spectrum.Add(colorIndex, nextColor); } } return(spectrum); }
// generate the entire spectrum of hues in the hsv color space (this includes magenta, which is not in the wavelength spectrum) // the key in the dictionary is the cumulative percieved color difference from the previous color // we're using the color difference because it's really easy to tell apart some colors (like blues) while it's hard to tell apart others (like greens) /// <summary> /// Gets colors for players, allies have similar colors /// </summary> /// <param name="playerCounts">Array of player counts in different teams</param> /// <returns>Array of colors in a team</returns> public static Color[][] GetTeamColors(int[] playerCounts) { Dictionary <int, Color> allColors = GetColorSpectrum(); double maxColorIndex = allColors.Max(kvp => kvp.Key); int teamCount = playerCounts.Length; var teamColors = new Color[teamCount][]; // part of the spectrum that is used to separate teams const double colorSeparation = 0.33; // width of the section of the spectrum that gets assigned to one team double teamSpectrumSliceWidth = maxColorIndex / teamCount * (1 - colorSeparation); for (int teamID = 0; teamID < teamCount; teamID++) { // color at which the team spectrum slice starts double startColor = teamID * maxColorIndex / teamCount; // all colors inside the spectrum slice assigned to the team KeyValuePair <int, Color>[] teamSpectrum = allColors.Where(kvp => kvp.Key > startColor && kvp.Key < startColor + teamSpectrumSliceWidth).OrderBy(kvp => kvp.Key).ToArray(); int playerCount = playerCounts[teamID]; var playerColors = new Color[playerCount]; for (int playerID = 0; playerID < playerCount; playerID++) { // get equally spaced colors for players inside a team int playerColorPercentile = playerID * teamSpectrum.Length / playerCount; Color playerColor = teamSpectrum[playerColorPercentile].Value; // consecutive colors can be hard to tell apart, so make the brightness vary playerColor = RGBHSL.SetBrightness(playerColor, playerID % 2 < 0.1 ? 0.4 : 0.6); playerColors[playerID] = playerColor; } teamColors[teamID] = playerColors; } return(teamColors); }