Color: as many unique color (vectors) as objects?



  • On 28/02/2014 at 14:45, xxxxxxxx wrote:

    Hi everyone,

    I want to assign every object a unique Color in the editor, the script works so far, but I am having trouble spacing and feeding the color vector with adequate numbers to have enough differentiation and not to exceed the 3 integers.

    lets say I have 254*254*254 = 16387064 Colors at my disposal and I have 2Mio Objects. How do i feed the vector with a spacing (color differentiation) while having 3 parameters.

    The cherry on top would be to exclude black, and white.

      
    counter = 2000000 # e.g. Number of Objects   
    step = (1/float(counter)) # somehow gives me a step but not robust   
      
    def getcolor (step, counter, secondcounter) :   
        colorvec = (step * secondcounter)   
        color = c4d.Vector(colorvec , colorvec , colorvec) # of course this alters all three vectors which limits me in color spacing ....   
        return color   
    

    thanks for your help in advance.
    mogh



  • On 28/02/2014 at 18:18, xxxxxxxx wrote:

    Give this a try.
    It should theoretically generate a ton of unique colors.

    import c4d  
    import random  
      
    def main() :  
        
      #Create a list array to hold all of the vector colors  
      colors = []  
      
      num_Colors = 100   #<--- Change this number as desired  
        
      #Generate lots of colors values between 0-255 using random  
      #Then test to see if the color already exist in the colors list  
      #If the color already exists..start the loop over again  
      #If the color is not in the list...Add it to the list  
      for i in xrange(num_Colors) :  
          vec = c4d.Vector(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))  
      
          if vec in colors: continue  
          else: colors.append(vec)  
            
      print colors  
      
    if __name__=='__main__':  
      main()
    

    -ScottA



  • On 01/03/2014 at 13:20, xxxxxxxx wrote:

    Hi ScottA,

    i tried this because your script didn't produce valid color vectors, found some similar script for random colors which had this division by 256 incorporated, don't know if this is the real deal but it gives me colors.

    Anyway i still have trouble to exclude black and white, when the script finds the vec in the list it continues but does not add another value it seems, hence I get index out of range errors.

    any idea?

    def random_unique_colors(howmany) : #Create a list array to hold all of the vector colors   
        colors = []   
        white = c4d.Vector(1,1,1)   
        black = c4d.Vector(0,0,0)   
        for i in xrange(howmany) :   
            vec = c4d.Vector(random.randint(0, 255)/256.0, random.randint(0, 255)/256.0, random.randint(0, 255)/256.0)   
            if vec in colors or vec == white or vec == black: continue   
            else: colors.append(vec)   
        return colors
    


  • On 01/03/2014 at 14:07, xxxxxxxx wrote:

    Sorry to bother,
    i tried it with 70.000 Objects and not getting nearly as many colors in the list - something is definitely wrong and slow.

    I guess i really need some sort of "step" solution.



  • On 01/03/2014 at 15:37, xxxxxxxx wrote:

    If you want values between 0-1 instead of 0-255. Then try it like this:

    import c4d  
    import random  
      
    def main() :  
        
      #Create a list array to hold all of the vector colors  
      colors = []  
      
      num_Colors = 100   #<--- Change this number as desired  
        
      #Generate lots of colors values between 0-255 using random  
      #Then test to see if the color already exist in the colors list  
      #If the color already exists..start the loop over again  
      #If the color is not in the list...Add it to the list  
      for i in xrange(num_Colors) :  
          vec = c4d.Vector(float(random.randint(0, 255)/100.0), float(random.randint(0, 255)/100.0), float(random.randint(0, 255)/100.0))  
      
          if vec in colors: continue  
          else: colors.append(vec)  
            
      print colors  
      
    if __name__=='__main__':  
      main()
    

    This is going to be very slow because
    a.) It's generating huge amounts of data
    b.) It's looking through the list for already existing values every iteration of the loop. Which takes longer...depending on how many vectors are in the list.

    I'm sure there's faster more optimized ways to generate large numbers of vectors. I just came up with this code off the top of my head.
    If you don't mind the generated colors being sequential. Simply incrementing the values per loop iteration, and deleting all the random and the "if vec in colors:"  code I used, will speed it up a lot.
    I just assumed that you didn't want the color values to be sequential.

    -ScottA



  • On 02/03/2014 at 04:59, xxxxxxxx wrote:

    Hi
    If you want to limit the color range it might be easier to start in HSV.

      
    import c4d   
    from random import randint, randrange   
    from c4d import utils   
      
    def main() :   
        howMany = 1000   
        colors = []   
      
        # Change min/max to limit hue range ( degrees )   
        hueMin = 0   
        hueMax = 360       
           
        # Change min/max to limit saturation range ( % )   
        saturationMin = 0   
        saturationMax = 100   
           
        # Change min/max lo limit value range ( % )   
        valueMin = 0   
        valueMax = 100   
           
        for i in xrange(howMany) :   
            h = float(randrange( hueMin, hueMax )) / 360   
            s = float(randrange( saturationMin, saturationMax )) / 100   
            v = float(randrange( valueMin, valueMax )) / 100   
      
            # Convert hsv to rgb and append new value to list   
            colors.append(c4d.utils.HSVToRGB( c4d.Vector(h, s, v) ))   
      
        print colors   
      
    if __name__=='__main__':   
        main()
    

    I'm not sure if all these colors are completely unique.

    Cheers
    Bonsak

    PS How do i set the line spacing inside the code block?



  • On 02/03/2014 at 05:06, xxxxxxxx wrote:

    Thanks for all your answers,

    I came up with a quiet dirty method manipulating a string, but it works good and isn't to slow after all.

    I do not need random! I need unique and well spaced colors because I am trying to code a object visibility plugin.

    def unique_colors(howmany) : #Create a list array to hold all of the vector colors   
        if howmany == 0:   
            return False   
           
        colors = []   
        step = 999999998 / howmany # 0.999 0.999 0.999 divided by the objectcount   
        largestring = 1000000001 + (step/2) # puts the range in the middle betweeen black and white   
      
        for i in xrange(howmany) :          
            r = float(str(largestring)[1:-6])/1000   
            g = float(str(largestring)[4:-3])/1000   
            b = float(str(largestring)[7:])/1000   
            colors.append(c4d.Vector(r , g, b))   
            largestring = largestring + step   
        return colors   
    


  • On 02/03/2014 at 12:33, xxxxxxxx wrote:

    I see. So you need a narrow range of hues, or the full spectrum devided evenly among the members?

    Cheers
    Bonsak



  • On 02/03/2014 at 13:02, xxxxxxxx wrote:

    I need full spectrum devided evenly among the members, without black and white to prevent errors with the background.

    kind regards
    mogh



  • On 18/03/2014 at 13:57, xxxxxxxx wrote:

    Still searching for a clean solution,

    found this but can't implement it

    http://stackoverflow.com/questions/470690/how-to-automatically-generate-n-distinct-colors

    kind regards



  • On 10/04/2014 at 03:27, xxxxxxxx wrote:

    found something:

    g = itertools.product(range(1,255), repeat=3) # range excluding 0 and 256   
    for x in manycolors:   
        color = g.next()   
    

    this creates as many colors as often you call g.next()

    kind regards


Log in to reply