문제

내가 쓴 두 아래 방법들을 통해 자동으로 선택 N 뚜렷한 색상입니다.그것은 작품에 의해 정의 구분의 선형적 기능에 RGB 습니다.이 방법의 장점을 얻을 수도 있습니다 진보적인 규모의 경우는 당신이 무엇을 원하지만,때 N 얻는 큰 색상을 시작할 수 있습니다 비슷하게 생겼습니다.내가 상상도 할 수 균일하게 세분화 RGB 큐브로 격자 그리고 그 때 포인트입니다.누가 알고있는 어떤 다른 방법이 있나요?나는 판결을 밖으로 목록을 정의하고 그냥 사이클링됩니다.나도 한 말을 하지 않는 일반적으로 관리하는 경우 그들은 충돌 또는 보이지 않는 좋은,그들은 단지가 시각적으로 별개입니다.

public static List<Color> pick(int num) {
    List<Color> colors = new ArrayList<Color>();
    if (num < 2)
        return colors;
    float dx = 1.0f / (float) (num - 1);
    for (int i = 0; i < num; i++) {
        colors.add(get(i * dx));
    }
    return colors;
}

public static Color get(float x) {
    float r = 0.0f;
    float g = 0.0f;
    float b = 1.0f;
    if (x >= 0.0f && x < 0.2f) {
        x = x / 0.2f;
        r = 0.0f;
        g = x;
        b = 1.0f;
    } else if (x >= 0.2f && x < 0.4f) {
        x = (x - 0.2f) / 0.2f;
        r = 0.0f;
        g = 1.0f;
        b = 1.0f - x;
    } else if (x >= 0.4f && x < 0.6f) {
        x = (x - 0.4f) / 0.2f;
        r = x;
        g = 1.0f;
        b = 0.0f;
    } else if (x >= 0.6f && x < 0.8f) {
        x = (x - 0.6f) / 0.2f;
        r = 1.0f;
        g = 1.0f - x;
        b = 0.0f;
    } else if (x >= 0.8f && x <= 1.0f) {
        x = (x - 0.8f) / 0.2f;
        r = 1.0f;
        g = 0.0f;
        b = x;
    }
    return new Color(r, g, b);
}
도움이 되었습니까?

해결책

당신은 사용할 수 있습니다 HSL 컬러 모델 색상을 만듭니다.

원하는 것은 색조가 다르고 가벼움이나 채도에 대한 약간의 변형이라면 다음과 같은 색조를 배포 할 수 있습니다.

// assumes hue [0, 360), saturation [0, 100), lightness [0, 100)

for(i = 0; i < 360; i += 360 / num_colors) {
    HSLColor c;
    c.hue = i;
    c.saturation = 90 + randf() * 10;
    c.lightness = 50 + randf() * 10;

    addColor(c);
}

다른 팁

이 질문은 꽤 많은 토론에 나타납니다.

다른 솔루션이 제안되지만 최적은 없습니다. 운 좋게, 과학 구조에옵니다

임의의 n

마지막 2는 대부분의 대학 도서관 / 프록시를 통해 무료입니다.

N은 유한하고 비교적 작습니다

이 경우 목록 솔루션을 사용할 수 있습니다. 주제의 매우 흥미로운 기사는 자유롭게 이용 가능합니다.

고려해야 할 몇 가지 색상 목록이 있습니다.

  • 거의 혼란스럽지 않은 Boynton의 11 가지 색상 목록 (이전 섹션의 첫 번째 논문에서 사용할 수 있음)
  • 켈리의 22 가지 최대 대비 (위의 논문에서 제공)

나도 뛰어 들었다 이것 MIT 학생의 팔레트. 마지막으로, 다음 링크는 서로 다른 색상 시스템 / 좌표 사이를 변환하는 데 유용 할 수 있습니다 (예 : 기사의 일부 색상은 RGB에 지정되지 않습니다).

Kelly와 Boynton의 목록의 경우 이미 RGB로 전환했습니다 (흰색과 검은 색을 제외하고는 분명해야합니다). 일부 C# 코드 :

public static ReadOnlyCollection<Color> KellysMaxContrastSet
{
    get { return _kellysMaxContrastSet.AsReadOnly(); }
}

private static readonly List<Color> _kellysMaxContrastSet = new List<Color>
{
    UIntToColor(0xFFFFB300), //Vivid Yellow
    UIntToColor(0xFF803E75), //Strong Purple
    UIntToColor(0xFFFF6800), //Vivid Orange
    UIntToColor(0xFFA6BDD7), //Very Light Blue
    UIntToColor(0xFFC10020), //Vivid Red
    UIntToColor(0xFFCEA262), //Grayish Yellow
    UIntToColor(0xFF817066), //Medium Gray

    //The following will not be good for people with defective color vision
    UIntToColor(0xFF007D34), //Vivid Green
    UIntToColor(0xFFF6768E), //Strong Purplish Pink
    UIntToColor(0xFF00538A), //Strong Blue
    UIntToColor(0xFFFF7A5C), //Strong Yellowish Pink
    UIntToColor(0xFF53377A), //Strong Violet
    UIntToColor(0xFFFF8E00), //Vivid Orange Yellow
    UIntToColor(0xFFB32851), //Strong Purplish Red
    UIntToColor(0xFFF4C800), //Vivid Greenish Yellow
    UIntToColor(0xFF7F180D), //Strong Reddish Brown
    UIntToColor(0xFF93AA00), //Vivid Yellowish Green
    UIntToColor(0xFF593315), //Deep Yellowish Brown
    UIntToColor(0xFFF13A13), //Vivid Reddish Orange
    UIntToColor(0xFF232C16), //Dark Olive Green
};

public static ReadOnlyCollection<Color> BoyntonOptimized
{
    get { return _boyntonOptimized.AsReadOnly(); }
}

private static readonly List<Color> _boyntonOptimized = new List<Color>
{
    Color.FromArgb(0, 0, 255),      //Blue
    Color.FromArgb(255, 0, 0),      //Red
    Color.FromArgb(0, 255, 0),      //Green
    Color.FromArgb(255, 255, 0),    //Yellow
    Color.FromArgb(255, 0, 255),    //Magenta
    Color.FromArgb(255, 128, 128),  //Pink
    Color.FromArgb(128, 128, 128),  //Gray
    Color.FromArgb(128, 0, 0),      //Brown
    Color.FromArgb(255, 128, 0),    //Orange
};

static public Color UIntToColor(uint color)
{
    var a = (byte)(color >> 24);
    var r = (byte)(color >> 16);
    var g = (byte)(color >> 8);
    var b = (byte)(color >> 0);
    return Color.FromArgb(a, r, g, b);
}

그리고 다음은 16 진수 및 8 비트-채널 표현의 RGB 값입니다.

kelly_colors_hex = [
    0xFFB300, # Vivid Yellow
    0x803E75, # Strong Purple
    0xFF6800, # Vivid Orange
    0xA6BDD7, # Very Light Blue
    0xC10020, # Vivid Red
    0xCEA262, # Grayish Yellow
    0x817066, # Medium Gray

    # The following don't work well for people with defective color vision
    0x007D34, # Vivid Green
    0xF6768E, # Strong Purplish Pink
    0x00538A, # Strong Blue
    0xFF7A5C, # Strong Yellowish Pink
    0x53377A, # Strong Violet
    0xFF8E00, # Vivid Orange Yellow
    0xB32851, # Strong Purplish Red
    0xF4C800, # Vivid Greenish Yellow
    0x7F180D, # Strong Reddish Brown
    0x93AA00, # Vivid Yellowish Green
    0x593315, # Deep Yellowish Brown
    0xF13A13, # Vivid Reddish Orange
    0x232C16, # Dark Olive Green
    ]

kelly_colors = dict(vivid_yellow=(255, 179, 0),
                    strong_purple=(128, 62, 117),
                    vivid_orange=(255, 104, 0),
                    very_light_blue=(166, 189, 215),
                    vivid_red=(193, 0, 32),
                    grayish_yellow=(206, 162, 98),
                    medium_gray=(129, 112, 102),

                    # these aren't good for people with defective color vision:
                    vivid_green=(0, 125, 52),
                    strong_purplish_pink=(246, 118, 142),
                    strong_blue=(0, 83, 138),
                    strong_yellowish_pink=(255, 122, 92),
                    strong_violet=(83, 55, 122),
                    vivid_orange_yellow=(255, 142, 0),
                    strong_purplish_red=(179, 40, 81),
                    vivid_greenish_yellow=(244, 200, 0),
                    strong_reddish_brown=(127, 24, 13),
                    vivid_yellowish_green=(147, 170, 0),
                    deep_yellowish_brown=(89, 51, 21),
                    vivid_reddish_orange=(241, 58, 19),
                    dark_olive_green=(35, 44, 22))

모든 Java 개발자에게는 Javafx 색상이 있습니다.

// Don't forget to import javafx.scene.paint.Color;

private static final Color[] KELLY_COLORS = {
    Color.web("0xFFB300"),    // Vivid Yellow
    Color.web("0x803E75"),    // Strong Purple
    Color.web("0xFF6800"),    // Vivid Orange
    Color.web("0xA6BDD7"),    // Very Light Blue
    Color.web("0xC10020"),    // Vivid Red
    Color.web("0xCEA262"),    // Grayish Yellow
    Color.web("0x817066"),    // Medium Gray

    Color.web("0x007D34"),    // Vivid Green
    Color.web("0xF6768E"),    // Strong Purplish Pink
    Color.web("0x00538A"),    // Strong Blue
    Color.web("0xFF7A5C"),    // Strong Yellowish Pink
    Color.web("0x53377A"),    // Strong Violet
    Color.web("0xFF8E00"),    // Vivid Orange Yellow
    Color.web("0xB32851"),    // Strong Purplish Red
    Color.web("0xF4C800"),    // Vivid Greenish Yellow
    Color.web("0x7F180D"),    // Strong Reddish Brown
    Color.web("0x93AA00"),    // Vivid Yellowish Green
    Color.web("0x593315"),    // Deep Yellowish Brown
    Color.web("0xF13A13"),    // Vivid Reddish Orange
    Color.web("0x232C16"),    // Dark Olive Green
};

다음은 위의 순서에 따라 분류되지 않은 켈리 색상입니다.

unsorted kelly colors

다음은 색조에 따른 분류 된 켈리 색상입니다 (일부 노란색은 그다지 대조적이지 않음)

 sorted kelly colors

Uri Cohen의 답변처럼 대신 발전기입니다. 색상을 멀리 사용하여 시작합니다. 결정 론적.

샘플, 왼쪽 색상 먼저 :sample

#!/usr/bin/env python3.3
import colorsys
import itertools
from fractions import Fraction

def zenos_dichotomy():
    """
    http://en.wikipedia.org/wiki/1/2_%2B_1/4_%2B_1/8_%2B_1/16_%2B_%C2%B7_%C2%B7_%C2%B7
    """
    for k in itertools.count():
        yield Fraction(1,2**k)

def getfracs():
    """
    [Fraction(0, 1), Fraction(1, 2), Fraction(1, 4), Fraction(3, 4), Fraction(1, 8), Fraction(3, 8), Fraction(5, 8), Fraction(7, 8), Fraction(1, 16), Fraction(3, 16), ...]
    [0.0, 0.5, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875, 0.0625, 0.1875, ...]
    """
    yield 0
    for k in zenos_dichotomy():
        i = k.denominator # [1,2,4,8,16,...]
        for j in range(1,i,2):
            yield Fraction(j,i)

bias = lambda x: (math.sqrt(x/3)/Fraction(2,3)+Fraction(1,3))/Fraction(6,5) # can be used for the v in hsv to map linear values 0..1 to something that looks equidistant

def genhsv(h):
    for s in [Fraction(6,10)]: # optionally use range
        for v in [Fraction(8,10),Fraction(5,10)]: # could use range too
            yield (h, s, v) # use bias for v here if you use range

genrgb = lambda x: colorsys.hsv_to_rgb(*x)

flatten = itertools.chain.from_iterable

gethsvs = lambda: flatten(map(genhsv,getfracs()))

getrgbs = lambda: map(genrgb, gethsvs())

def genhtml(x):
    uint8tuple = map(lambda y: int(y*255), x)
    return "rgb({},{},{})".format(*uint8tuple)

gethtmlcolors = lambda: map(genhtml, getrgbs())

if __name__ == "__main__":
    print(list(itertools.islice(gethtmlcolors(), 100)))

여기 아이디어가 있습니다. HSV 실린더를 상상해보십시오

밝기와 채도에 대해 원하는 상한 및 하한을 정의하십시오. 이것은 공간 내에서 정사각형 단면 링을 정의합니다.

이제이 공간 내에서 N 포인트를 무작위로 흩어지게합니다.

그런 다음 고정 된 수의 반복 또는 포인트가 안정화 될 때까지 반복적 인 반발 알고리즘을 적용하십시오.

이제 관심있는 색상 공간 내에서 가능한 한 다른 N 색상을 나타내는 N 포인트가 있어야합니다.

휴고

앞으로 나올 세대를 위해 나는 여기에 python에서 받아 들여진 답을 추가합니다.

import numpy as np
import colorsys

def _get_colors(num_colors):
    colors=[]
    for i in np.arange(0., 360., 360. / num_colors):
        hue = i/360.
        lightness = (50 + np.random.rand() * 10)/100.
        saturation = (90 + np.random.rand() * 10)/100.
        colors.append(colorsys.hls_to_rgb(hue, lightness, saturation))
    return colors

모든 사람들은 인간의 시각 시스템에서 인식 된 색상 차이를 나타내도록 설계된 매우 유용한 YUV 색상 공간의 존재를 놓친 것 같습니다. YUV의 거리는 인간 인식의 차이를 나타냅니다. 4 차원 루빅스 큐브와 임의의 수의 얼굴을 가진 다른 4D 트위스트 퍼즐을 구현하는 MagicCube4D 의이 기능이 필요했습니다.

내 솔루션은 YUV에서 랜덤 포인트를 선택한 다음 가장 가까운 2 점을 반복적으로 분해하고 결과를 반환 할 때만 RGB로만 변환하여 시작합니다. 이 방법은 O (n^3)이지만 적은 숫자 나 캐시 할 수있는 경우에는 중요하지 않습니다. 확실히 더 효율적일 수 있지만 결과는 우수한 것으로 보입니다.

이 기능은 주어진 양보다 더 밝거나 어두운 색상을 생성하지 않도록 밝기 임계 값의 선택적 사양을 허용합니다. 즉, 흑백에 가까운 값을 원하지 않을 수 있습니다. 결과 색상이 나중에 조명, 레이어링, 투명성 등을 통해 음영 처리 된 기본 색상으로 사용될 때 유용하며 여전히 기본 색상과는 다른 것처럼 보일 때 유용합니다.

import java.awt.Color;
import java.util.Random;

/**
 * Contains a method to generate N visually distinct colors and helper methods.
 * 
 * @author Melinda Green
 */
public class ColorUtils {
    private ColorUtils() {} // To disallow instantiation.
    private final static float
        U_OFF = .436f,
        V_OFF = .615f;
    private static final long RAND_SEED = 0;
    private static Random rand = new Random(RAND_SEED);    

    /*
     * Returns an array of ncolors RGB triplets such that each is as unique from the rest as possible
     * and each color has at least one component greater than minComponent and one less than maxComponent.
     * Use min == 1 and max == 0 to include the full RGB color range.
     * 
     * Warning: O N^2 algorithm blows up fast for more than 100 colors.
     */
    public static Color[] generateVisuallyDistinctColors(int ncolors, float minComponent, float maxComponent) {
        rand.setSeed(RAND_SEED); // So that we get consistent results for each combination of inputs

        float[][] yuv = new float[ncolors][3];

        // initialize array with random colors
        for(int got = 0; got < ncolors;) {
            System.arraycopy(randYUVinRGBRange(minComponent, maxComponent), 0, yuv[got++], 0, 3);
        }
        // continually break up the worst-fit color pair until we get tired of searching
        for(int c = 0; c < ncolors * 1000; c++) {
            float worst = 8888;
            int worstID = 0;
            for(int i = 1; i < yuv.length; i++) {
                for(int j = 0; j < i; j++) {
                    float dist = sqrdist(yuv[i], yuv[j]);
                    if(dist < worst) {
                        worst = dist;
                        worstID = i;
                    }
                }
            }
            float[] best = randYUVBetterThan(worst, minComponent, maxComponent, yuv);
            if(best == null)
                break;
            else
                yuv[worstID] = best;
        }

        Color[] rgbs = new Color[yuv.length];
        for(int i = 0; i < yuv.length; i++) {
            float[] rgb = new float[3];
            yuv2rgb(yuv[i][0], yuv[i][1], yuv[i][2], rgb);
            rgbs[i] = new Color(rgb[0], rgb[1], rgb[2]);
            //System.out.println(rgb[i][0] + "\t" + rgb[i][1] + "\t" + rgb[i][2]);
        }

        return rgbs;
    }

    public static void hsv2rgb(float h, float s, float v, float[] rgb) {
        // H is given on [0->6] or -1. S and V are given on [0->1]. 
        // RGB are each returned on [0->1]. 
        float m, n, f;
        int i;

        float[] hsv = new float[3];

        hsv[0] = h;
        hsv[1] = s;
        hsv[2] = v;
        System.out.println("H: " + h + " S: " + s + " V:" + v);
        if(hsv[0] == -1) {
            rgb[0] = rgb[1] = rgb[2] = hsv[2];
            return;
        }
        i = (int) (Math.floor(hsv[0]));
        f = hsv[0] - i;
        if(i % 2 == 0)
            f = 1 - f; // if i is even 
        m = hsv[2] * (1 - hsv[1]);
        n = hsv[2] * (1 - hsv[1] * f);
        switch(i) {
            case 6:
            case 0:
                rgb[0] = hsv[2];
                rgb[1] = n;
                rgb[2] = m;
                break;
            case 1:
                rgb[0] = n;
                rgb[1] = hsv[2];
                rgb[2] = m;
                break;
            case 2:
                rgb[0] = m;
                rgb[1] = hsv[2];
                rgb[2] = n;
                break;
            case 3:
                rgb[0] = m;
                rgb[1] = n;
                rgb[2] = hsv[2];
                break;
            case 4:
                rgb[0] = n;
                rgb[1] = m;
                rgb[2] = hsv[2];
                break;
            case 5:
                rgb[0] = hsv[2];
                rgb[1] = m;
                rgb[2] = n;
                break;
        }
    }


    // From http://en.wikipedia.org/wiki/YUV#Mathematical_derivations_and_formulas
    public static void yuv2rgb(float y, float u, float v, float[] rgb) {
        rgb[0] = 1 * y + 0 * u + 1.13983f * v;
        rgb[1] = 1 * y + -.39465f * u + -.58060f * v;
        rgb[2] = 1 * y + 2.03211f * u + 0 * v;
    }

    public static void rgb2yuv(float r, float g, float b, float[] yuv) {
        yuv[0] = .299f * r + .587f * g + .114f * b;
        yuv[1] = -.14713f * r + -.28886f * g + .436f * b;
        yuv[2] = .615f * r + -.51499f * g + -.10001f * b;
    }

    private static float[] randYUVinRGBRange(float minComponent, float maxComponent) {
        while(true) {
            float y = rand.nextFloat(); // * YFRAC + 1-YFRAC);
            float u = rand.nextFloat() * 2 * U_OFF - U_OFF;
            float v = rand.nextFloat() * 2 * V_OFF - V_OFF;
            float[] rgb = new float[3];
            yuv2rgb(y, u, v, rgb);
            float r = rgb[0], g = rgb[1], b = rgb[2];
            if(0 <= r && r <= 1 &&
                0 <= g && g <= 1 &&
                0 <= b && b <= 1 &&
                (r > minComponent || g > minComponent || b > minComponent) && // don't want all dark components
                (r < maxComponent || g < maxComponent || b < maxComponent)) // don't want all light components

                return new float[]{y, u, v};
        }
    }

    private static float sqrdist(float[] a, float[] b) {
        float sum = 0;
        for(int i = 0; i < a.length; i++) {
            float diff = a[i] - b[i];
            sum += diff * diff;
        }
        return sum;
    }

    private static double worstFit(Color[] colors) {
        float worst = 8888;
        float[] a = new float[3], b = new float[3];
        for(int i = 1; i < colors.length; i++) {
            colors[i].getColorComponents(a);
            for(int j = 0; j < i; j++) {
                colors[j].getColorComponents(b);
                float dist = sqrdist(a, b);
                if(dist < worst) {
                    worst = dist;
                }
            }
        }
        return Math.sqrt(worst);
    }

    private static float[] randYUVBetterThan(float bestDistSqrd, float minComponent, float maxComponent, float[][] in) {
        for(int attempt = 1; attempt < 100 * in.length; attempt++) {
            float[] candidate = randYUVinRGBRange(minComponent, maxComponent);
            boolean good = true;
            for(int i = 0; i < in.length; i++)
                if(sqrdist(candidate, in[i]) < bestDistSqrd)
                    good = false;
            if(good)
                return candidate;
        }
        return null; // after a bunch of passes, couldn't find a candidate that beat the best.
    }


    /**
     * Simple example program.
     */
    public static void main(String[] args) {
        final int ncolors = 10;
        Color[] colors = generateVisuallyDistinctColors(ncolors, .8f, .3f);
        for(int i = 0; i < colors.length; i++) {
            System.out.println(colors[i].toString());
        }
        System.out.println("Worst fit color = " + worstFit(colors));
    }

}

다음은 "고유 한"문제를 관리하는 솔루션입니다.

반발 충전으로 단위 구체와 드롭 포인트를 만듭니다. 더 이상 움직이지 않을 때까지 입자 시스템을 실행하십시오 (또는 델타는 "충분히 작습니다). 이 시점에서 각 지점은 가능한 한 서로 멀리 떨어져 있습니다. (x, y, z)를 RGB로 변환합니다.

특정 종류의 문제의 경우 이러한 유형의 솔루션이 무차별 대비보다 더 잘 작동 할 수 있기 때문에 언급합니다.

나는 원래 보았다 이 접근법은 여기에 있습니다 구의 테일링을 위해.

다시 말하지만, HSL 공간 또는 RGB 공간을 가로 지르는 가장 분명한 솔루션은 아마도 잘 작동 할 것입니다.

내가 하려고 해결하는 채도의 성격을 나타냅 최대와에 초점을 훼니다.그것을 보고,서 갈 수 있는 0 에서 255 까지고 그 주위를 감싸.지금 당신이 원하는 두 가지 대조 색깔을 가면서 이 고리,즉0 128.당신이 원하는 4 가지 색상을 몇 가지로 구분하여 1/4 의 256 의 길이 원형,즉0,64,128,192.그리고 물론,다른 사람으로 제안해야 할 때 N 색상,당신은 그냥 그들을 분리하여 256/N.

내가 무엇을 추가하는 것이 아이디어가 사용하는 반전의 표현을 바이너리 숫자를 형상이 순서입니다.이보:

0 = 00000000  after reversal is 00000000 = 0
1 = 00000001  after reversal is 10000000 = 128
2 = 00000010  after reversal is 01000000 = 64
3 = 00000011  after reversal is 11000000 = 192

...이 방법은 필요하신 경우 N 다른 색상이 있습니다 첫 번째 N 숫자,리버스,그리고 당신은 많은 것을 먼 가능한 포인트(N 되는 힘의 두)하는 동안 같은 시간에 보존하는 각 접두사의 시퀀스는 다릅니다 많이있다.

이것은 중요한 목표에 사용 사례로,나는 차트는 색상이 정렬된 지역에 의하여 이 컬러입니다.내가 원하는 가장 큰 영역을 차트의 큰 반면,나는 확인을 함께 몇 가지 작은 영역을 색상의 유사한 사람들에게는 최고 10 으로,그것은 분명에 대한 독자 어느 것 하나로 관찰하는 지역입니다.

HSL 모델 행하라 그리하면 복을 받으리라에 적합하"분류"라는 색상이지만,당신이 시각적으로 뚜렷한 색상 당신은 확실히 필요 실험 색상 모델을 대신 합니다.

CIELAB 할 수 있도록 설계되었 균일한 지각과 관련하여 인간의 컬러의 비전을 의미하는 같은 양의 수치 이러한 값을 변경에 대응하는 동일 금액의 시각적으로 인식되고 변합니다.

일단 당신이 알고,는 최적의 하위 집합 N 색상에서 다양한 범위의 색상은 여전히(NP)어려운 문제,의 종류와 유사한 여행 외판원 문제 모든 솔루션을 사용하여 k-의미 알고리즘이나 뭔가지 않을 것이 정말 도움이 됩니다.

는 말했다,N 경우는 너무 크지 않고 시작하는 경우 제한된 색을 것입니다,당신은 쉽게 찾을 수 있는 매우 좋은 하위 집합의 distincts 색상에 따라 실험실의 거리 간단한 임의의 기능입니다.

내가 코드화와 같은 도구에 대한 나의 자신의 사용을(당신은 여기에서 찾을 수 있습니다: https://mokole.com/palette.html다)여기에서는 내가 무엇을 가지고 대한 N=7:enter image description here

그것은 모든 자바 스크립트를 살펴보 소스에서의 페이지와 적응을 위해 그것을 당신의 자신의 필요합니다.

N이 충분히 크면 비슷한 색상을 얻을 수 있습니다. 세상에는 너무 많습니다.

왜 그렇게 스펙트럼을 통해 고르게 배포하지 않는가 :

IEnumerable<Color> CreateUniqueColors(int nColors)
{
    int subdivision = (int)Math.Floor(Math.Pow(nColors, 1/3d));
    for(int r = 0; r < 255; r += subdivision)
        for(int g = 0; g < 255; g += subdivision)
            for(int b = 0; b < 255; b += subdivision)
                yield return Color.FromArgb(r, g, b);
}

비슷한 색상이 서로 옆에 있지 않도록 시퀀스를 혼합하려면 결과 목록을 셔플 할 수 있습니다.

내가 이것을 이해하고 있습니까?

이것은 MATLAB에서 사소한 것입니다 (HSV 명령이 있습니다) :

cmap = hsv(number_of_colors)

나는 r 호출에 대한 패키지를 썼다 Qualpalr 이를 위해 특별히 설계되었습니다. 나는 당신이 그것을 보는 것이 좋습니다 삽화 그것이 어떻게 작동하는지 알아 보려면 요점을 요약하려고 노력할 것입니다.

Qualpalr는 색상의 사양을 가져옵니다 HSL 색상 공간 (이 스레드에서 이전에 설명 된), DIN99D 색상 공간 (지각 적으로 균일)에 투사하고 n 이들은 OIF 사이의 최소 거리를 극대화합니다.

# Create a palette of 4 colors of hues from 0 to 360, saturations between
# 0.1 and 0.5, and lightness from 0.6 to 0.85
pal <- qualpal(n = 4, list(h = c(0, 360), s = c(0.1, 0.5), l = c(0.6, 0.85)))

# Look at the colors in hex format
pal$hex
#> [1] "#6F75CE" "#CC6B76" "#CAC16A" "#76D0D0"

# Create a palette using one of the predefined color subspaces
pal2 <- qualpal(n = 4, colorspace = "pretty")

# Distance matrix of the DIN99d color differences
pal2$de_DIN99d
#>        #69A3CC #6ECC6E #CA6BC4
#> 6ECC6E      22                
#> CA6BC4      21      30        
#> CD976B      24      21      21

plot(pal2)

enter image description here

이 간단한 재귀 알고리즘은 별개의 색조 값을 생성하기 위해 허용 된 답변을 보완한다고 생각합니다. HSV를 위해 만들었지 만 다른 색 공간에도 사용될 수 있습니다.

각 사이클에서 가능한 한 서로 별도의 사이클에서 색조를 생성합니다.

/**
 * 1st cycle: 0, 120, 240
 * 2nd cycle (+60): 60, 180, 300
 * 3th cycle (+30): 30, 150, 270, 90, 210, 330
 * 4th cycle (+15): 15, 135, 255, 75, 195, 315, 45, 165, 285, 105, 225, 345
 */
public static float recursiveHue(int n) {
    // if 3: alternates red, green, blue variations
    float firstCycle = 3;

    // First cycle
    if (n < firstCycle) {
        return n * 360f / firstCycle;
    }
    // Each cycle has as much values as all previous cycles summed (powers of 2)
    else {
        // floor of log base 2
        int numCycles = (int)Math.floor(Math.log(n / firstCycle) / Math.log(2));
        // divDown stores the larger power of 2 that is still lower than n
        int divDown = (int)(firstCycle * Math.pow(2, numCycles));
        // same hues than previous cycle, but summing an offset (half than previous cycle)
        return recursiveHue(n % divDown) + 180f / divDown;
    }
}

여기서는 이런 종류의 알고리즘을 찾을 수 없었습니다. 도움이되기를 바랍니다. 여기서 첫 번째 게시물입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top