目前在撰寫產生顏色的演算法上遇到困難,想請教一下這邊的大大有沒有什麼想法?
現在 input: properties 是個陣列,陣列內又有 property 物件,陣列的長度 n 代表需要產生 n 個顏色
期待的 output 是 n 個顏色,但有些限制
這些顏色不但不能一樣、相近色系(肉眼要可以明顯看出差異)
也不能是藍色、紫色及它們的相近色,也不能是黑色及接近黑色的深色
現在我的程式碼如下:
const getRandomColor = (properties) => {
const addColorProperties = [];
const initColor = Math.floor(Math.random() * 170);
properties.forEach((property, i) => {
const hue = Math.round((initColor + i * (170 / properties.length)) % 170);
let saturation = Math.floor(Math.random() * (100 - 20) + 20);
let lightness = Math.floor(Math.random() * (85 - 20) + 20);
addColorProperties.push({ ...property, color: `hsl(${hue}, ${saturation}%, ${lightness}%)` });
});
return addColorProperties;
}
想法就是從 hsl 這邊產生顏色,hue 從 0~170 取值,因為 170 以上就是藍色紫色的範圍了
saturation, lightness 隨機產生
https://www.w3schools.com/colors/colors_hsl.asp
這有明顯的缺點是若要產生的顏色越多越容易顏色相近...
若有更好、可以改良的地方希望大家可以告訴我,感恩!!
不要用亂數,因為RGB的範圍真的很大,R、G、B一個值就有有一個位元組就從0~255,三個乘起來就有一千多萬組,問題是眼睛沒辦法分辨這麼細的值(還沒算上色盲人士),要是一個不小心,random到鄰近值,那兩色差別,你怎麼辦?
最簡單的方式,用色差很大的List<Color>做表,每次取一個值,用過就抓下一個(用List.Count取餘數抓值),人多的話就把這個表色開設大一點
//我瞎寫的
List<Color> ColorArray = new List<Color>{
Color.FromArgb(255,255,0,0),
Color.FromArgb(255,0,255,0),
Color.FromArgb(255,0,0,255),
Color.FromArgb(255,50,0,0),
Color.FromArgb(255,0,50,0),
Color.FromArgb(255,0,0,50),
//.................
};
for(int i = 0 ;i = People.Count-1 ;i++){
var thisGuyColor = ColorArray[i % ColorArray.Count] ;
// .. 然後你就懂了
}
或是random一個0~15的值,讓色階數減少16倍
一樣跑Color.FromRGB()
丟進List<Color>裡
用過的不要加~~(用Contains檢查是否已存在)
Random rnd;
List<Color> arrColor = new List<Color>();
for (int i = 0; i < 100; i++)
{
while (true)
{
rnd = new Random(Guid.NewGuid().GetHashCode());
int R = (rnd.Next(16)+1)*16-1;
rnd = new Random(Guid.NewGuid().GetHashCode());
int G = (rnd.Next(16)+1)*16-1;
rnd = new Random(Guid.NewGuid().GetHashCode());
int B = (rnd.Next(16)+1)*16-1;
Color newColor = Color.FromArgb(255, R, G, B);
if (!arrColor.Contains(newColor))
{
arrColor.Add(newColor);
break; // 沒那麼倒霉連續都一樣而逃不出去吧?如果花生,那可以去簽威力彩了
}
}
}
好,謝謝大大詳細的回答
實際上之前也有考慮到需要配色的 properties 數量可能會超過會預先生成的一系列色票,所以才沒這麼做
不過我會再問看看要不要重新採用這個方式,感謝!
隨機產生數個顏色的演算法,顏色不能重複&相近
肉眼要可以明顯看出差異
關鍵在於「定義」什麼是肉眼可以明顯看出差異
然後才是如何寫程式
如果用我的老花眼做例子
什麼 S,L 我根本看不出差別
H 的值是 0-360 ,理論上有 361 種顏色
但是我的老花眼
最多只能看出7種顏色的差別
使用 HSL 亂數產生顏色時要有一個觀念
HSL 類似以 L 為對稱軸的雙圓錐體
所以要做得比較完美的話,不能單純取亂數
還要考慮:
雙圓錐體模型可參考:HSI顏色模型
也許可以定義雙圓錐上的直線距離作為顏色差異的參考
應該會得到比較好的結果