2013年4月22日月曜日

複数の色を均等に生成する

コンスタントに色々やる体制が整いつつあるkyamaです。こんばんは。
目指せ月イチアウトプット。

さて今日のお題は、「複数の要素に区別しやすい色を割り当てる方法」です。

いくつかの要素をカテゴリ分けして表示する際などに、カテゴリごとの色を作らないといけない、と言うことはそれなりにあると思います。
プラットフォームやフレームワークなどで提供されていれば悩む必要はないのですが、そういうものがない場合は当然自前で書くことになります。

このとき手っ取り早い方法は、以下の様なコードでランダムに色を選ぶことでしょうか。
var color = {r: 255, g: 255, b: 255};
color.r = Math.round(Math.random() * 255);
color.g = Math.round(Math.random() * 255);
color.b = Math.round(Math.random() * 255);

ただしこれは、重複した色や類似した色が生成されてしまい、実際には使いにくい場面もあります。
そのため、以下の様なコードで、色相を均等に分割して色を割り当てるのが妥当な落とし所ではないかと思っています。
// splitSize: 分割数
// index: 分割されたうちの何番目か
// return: RGBのオブジェクト。0から1までの値をとる。
function pickRGBColorOnCircle(splitSize, index) {
    var interval = 360.0 / splitSize;
    var hue = (index * interval);
    var sat = 1.0;
    var val = 1.0;
 
    // this code written in reference to the following site and Wikipedia.
    // http://www.technotype.net/tutorial/tutorial.php?fileId=%7BImage%20processing%7D&sectionId=%7B-converting-between-rgb-and-hsv-color-space%7D
    var hi = Math.floor(hue / 60.0) % 6;
    var f  = (hue / 60.0) - hi;
    var p  = val * (1.0 - sat);
    var q  = val * (1.0 - sat * f);
    var t  = val * (1.0 - sat * (1.0 - f));
 
    switch(hi) {
    case 0:
        return {
            r: val,
            g: t,
            b: p
        };
    case 1:
        return {
            r: q,
            g: val,
            b: p
        };
    case 2:
        return {
            r: p,
            g: val,
            b: t
        };
    case 3:
        return {
            r: p,
            g: q,
            b: val
        };
    case 4:
        return {
            r: t,
            g: p,
            b: val
        };
    case 5:
        return {
            r: val,
            g: p,
            b: q
        };
    default:
        throw new Error('unexpected error: args = ' + splitSize + ', ' + index);
    }
}

色相を分割する関係上、HSV表色系で色を特定した後にRGBに変換するようにしています。
現状は色相の開始位置を固定していますが、引数にoffsetなどを追加して変更できるようにすれば任意の位置から色の選択を開始できるはずです。

また上記のコードはGistにも置いているので、使いたい方はご自由にお使いください。
 https://gist.github.com/lazykyama/5429907
ライセンスは要らない気もしましたが、一応MITにしています。
ファイル名の変更などもご自由に。

しかしもう完全に備忘録ではなくなってきてますね…


0 件のコメント:

コメントを投稿