2010-08-04 86 views
5

爲了在GWT-Widget中表示具有不同顏色的對象列表,我們需要動態獲取與對象顏色不同的顏色列表。由於列表的大小可能會有所不同,我們需要能夠計算出這樣的顏色列表。如何動態計算顏色列表?

回答

6

我的解決方案的另一個版本範圍:

List<int> getUniqueColors(int amount) { 
    final int lowerLimit = 0x10; 
    final int upperLimit = 0xE0;  
    final int colorStep = (upperLimit-lowerLimit)/Math.pow(amount,1f/3); 

    final List<int> colors = new ArrayList<int>(amount); 

    for (int R = lowerLimit;R < upperLimit; R+=colorStep) 
     for (int G = lowerLimit;G < upperLimit; G+=colorStep) 
      for (int B = lowerLimit;B < upperLimit; B+=colorStep) { 
       if (colors.size() >= amount) { //The calculated step is not very precise, so this safeguard is appropriate 
        return colors; 
       } else { 
        int color = (R<<16)+(G<<8)+(B); 
        colors.add(color); 
       }    
      } 
    return colors; 
} 

這一個是更先進,因爲它產生彼此不同儘可能的顏色(像@aiiobe一樣)。

一般我們拆分至紅,綠,藍的3子範圍,計算出我們如何許多步驟需要遍歷每個人(通過應用POW(範圍,1F/3))和迭代他們。

以數字3爲例,它將生成0x0000B1, 0x00B100, 0x00B1B1。對於數字10,它將是:0x000076, 0x0000EC, 0x007600, 0x007676, 0x0076EC, 0x00EC00, 0x00EC76, 0x00ECEC, 0x760000, 0x760076

+1

如果你想跳過灰色 - 一些額外的計算將是必需的。你需要一些'if(r == g == b)然後在循環中繼續',還需要'Math.pow(amount,1f/3)'來增加'amount'跳過灰色可能)。 – bezmax 2010-08-04 09:16:49

+1

或者你可以堅持不同的色調;) – aioobe 2010-08-04 09:34:37

+0

是的,但我不擅長HSV,所以我提出了第一件事情,我想到了。 – bezmax 2010-08-04 09:46:54

5

這樣的事情我會猜。沒有隨機性,只是計算要採取的顏色步驟,並將所有顏色範圍拆分爲該步驟。如果限制下限 - 您將刪除太深的顏色,限制上限將消除太亮的顏色。

List<Integer> getUniqueColors(int amount) { 
    final int lowerLimit = 0x101010; 
    final int upperLimit = 0xE0E0E0; 
    final int colorStep = (upperLimit-lowerLimit)/amount; 

    final List<Integer> colors = new ArrayList<Integer>(amount); 
    for (int i=0;i<amount;i++) { 
     int color = lowerLimit+colorStep*i; 
     colors.add(color); 
    } 
    return colors; 
} 
+0

請在底部查看我的另一個版本的解決方案。它會產生比這更好的結果,但會稍微複雜一些。 – bezmax 2010-08-04 09:13:44

+0

這甚至沒有編譯。你不能在java中擁有'int'的'List'。您可能想要將其更改爲「Integer」。 – aioobe 2010-12-10 15:16:19

+0

是的,這是一個錯字。 – bezmax 2010-12-10 15:45:19

5

如果我瞭解您的情況正確,您是否看到多種顏色,看起來有點「儘可能不同」?我會在這種情況下建議你改變色調值(兩種紅色的亮度略有不同),所以你得到像「彩虹調色板」:

這可以通過以下代碼:

Color[] cols = new Color[n]; 
for (int i = 0; i < n; i++) 
    cols[i] = Color.getHSBColor((float) i/n, 1, 1); 

一個例子使用具有低於屏幕截圖:

import java.awt.*; 

public class TestComponent extends JPanel { 

    int numCols = 6; 

    public void paint(Graphics g) { 

     float h = 0, dh = (float) getHeight()/numCols; 
     Color[] cols = getDifferentColors(numCols); 

     for (int i = 0; i < numCols; i++) { 
      g.setColor(cols[i]); 
      g.fillRect(0, (int) h, getWidth(), (int) (h += dh)); 
     } 
    } 

    public static Color[] getDifferentColors(int n) { 
     Color[] cols = new Color[n]; 
     for (int i = 0; i < n; i++) 
      cols[i] = Color.getHSBColor((float) i/n, 1, 1); 
     return cols; 
    } 

    public static void main(String s[]) { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new TestComponent()); 
     f.setSize(200, 200); 
     f.setVisible(true); 
    } 
} 

numCols = 6numCols = 40產生了followi NG兩張截圖:

enter image description hereenter image description here

如果你需要一個像超過30種顏色,當然你可以改變亮度或許飽和度爲好,並且有,例如,10成深色,10種色調顏色,和10個鮮豔的色彩。