Ruby, Generate a random hex color (only light colors)
In this thread colour lumincance is described with a formula of
(0.2126*r) + (0.7152*g) + (0.0722*b)
The same formula for luminance is given in wikipedia (and it is taken from this publication). It reflects the human perception, with green being the most "intensive" and blue the least.
Therefore, you can select r, g, b until the luminance value goes above the division between light and dark (255 to 0). For example:
lum, ary = 0, []
while lum < 128
ary = (1..3).collect {rand(256)}
lum = ary[0]*0.2126 + ary[1]*0.7152 + ary[2]*0.0722
end
Another article refers to brightness, being the arithmetic mean of r, g and b. Note that brightness is even more subjective, as a given target luminance can elicit different perceptions of brightness in different contexts (in particular, the surrounding colours can affect your perception).
All in all, it depends on which colours you consider "light".
Ruby, Generate a random hex color
One-liner with unpack
:Random.new.bytes(3).unpack("H*")[0]
Since ruby 2.6.0 you can do it even shorter: Random.bytes(3).unpack1('H*')
Ruby color generator
Using RGB you will have harder times avoiding gray colors, as well as colors "difficult to see" (I'm guessing on a white background)
If you need them to be random, you can use HSV values to stay away from the white, gray and black spectra. That means you set a range in the value and saturation parameters (for example, ~175 to 255) while hue can be selected freely at random.
So, this may work:
def random_bright_color(threshold = 175)
hue = rand(256 - threshold) + threshold
saturation = rand(256 - threshold) + threshold
value = rand(256)
hsv_to_rgb(hue, saturation, value)
end
where
def hsv_to_rgb(h, s, v)
if s == 0
r = g = b = (v * 2.55).round
else
h /= 60.0
s /= 100.0
v /= 100.0
i = h.floor
f = h - i
p = v * (1 - s)
q = v * (1 - s * f)
t = v * (1 - s * (1 - f))
rgb = case i
when 0 then [v, t, p]
when 1 then [q, v, p]
when 2 then [q, v, t]
when 3 then [p, q, v]
when 4 then [t, p, v]
else [v, p, q]
end
end
rgb.map{|color| (color * 255).round}
end
is ported from here and the explanation can be found on the same Wikipedia article
However, if you additionally need to have random colors different from each other, perhaps the really true solution is to have them selected from a group of base colors, and select at random from that set.
How do I generate a random hex code that of a lighter color in javascript?
What I would do is generate a number from 00 to FF for each (RGB) (ie 000000
to FFFFFF
). I would also make sure the G value is approximately higher than 33.
Generating pastel colors
Try this:
start_color = 128 # minimal color amount
total_offset = 64 # sum of individual color offsets above the minimal amount
'#' +
[0, rand(total_offset), rand(total_offset), total_offset].sort.each_cons(2).map{|a,b|
"%02x" % (start_color+b-a)
}.join
Actually, here's tiny Sinatra app that you can play with and see the results instantly:
require 'sinatra'
def get_pastel start_color, total_offset
'#' +
[0, rand(total_offset), rand(total_offset), total_offset].sort.each_cons(2).map{|a,b|
"%02x" % (start_color+b-a)
}.join
end
get '/:start_color/:total_offset' do |start_color, total_offset|
(0..20).map{c = get_pastel(start_color.to_i, total_offset.to_i)
"<span style='background-color:#{c}'>#{c}</span>\n"
}.join
end
Then fire up the browser and see how it looks:
http://localhost:4567/192/64
http://localhost:4567/128/128
;)
Random color generator
Use getRandomColor()
in place of "#0000FF"
:
function getRandomColor() { var letters = '0123456789ABCDEF'; var color = '#'; for (var i = 0; i < 6; i++) { color += letters[Math.floor(Math.random() * 16)]; } return color;}
function setRandomColor() { $("#colorpad").css("background-color", getRandomColor());}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div id="colorpad" style="width:300px;height:300px;background-color:#000">
</div><button onclick="setRandomColor()">Random Color</button>
Problem in generating random colors - asp.net and c#
I may have misunderstood the question...
If the issue to avoid similar sequences of colors produced over time, see KMan's response which I think was the first one to suggest that by producing all random values out of the same generator (rather than producing one new generator each time), one avoids the risk of producing a generator with the same seed as a generator previously used.
If the concern is to avoid drawing two "similar" colors in a row, the following response should do. Avoiding two similar colors in a row implies either
- the use of some mathematical logic (but there is a risk that the functions used would not cover the spectrum of all possible colors as a decent Random Number Generator would)
- drawing true random colors, but refusing them (and trying anew) when they are deemed to similar.
The second approach is what is illustrated in the following snippet.
The style is longhand, and the color acceptance criteria is somewhat arbitrary but this should provide a good idea.
Furthermore, by reusing a single Random Number Generator (RNG), one avoid the risk of repeating sequences if somehow the RNG was created each time, and by chance the same seed was used...
const int minTotalDiff = 200; // parameter used in new color acceptance criteria
const int okSingleDiff = 100; // id.
int prevR, prevG, prevB; // R, G and B components of the previously issued color.
Random RandGen = null;
public string GetNewColor()
{
int newR, newG, newB;
if (RandGen == null)
{
RandGen = new Random();
prevR = prevG = prevB = 0;
}
bool found = false;
while (!found)
{
newR = RandGen.Next(255);
newG = RandGen.Next(255);
newB = RandGen.Next(255);
int diffR = Math.Abs(prevR - newR);
int diffG = Math.Abs(prevG - newG);
int diffB = Math.Abs(prevB - newB);
// we only take the new color if...
// Collectively the color components are changed by a certain
// minimum
// or if at least one individual colors is changed by "a lot".
if (diffR + diffG + diffB >= minTotalDiff
|| diffR >= okSingleDiff
|| diffR >= okSingleDiff
|| diffR >= okSingleDiff
)
found = true;
}
prevR = newR;
prevG = newG;
prevB = newB;
return String.Format("#{0:X2}{0:X2}{0:X2}", prevR, prevG, prevB);
}
Related Topics
Updating from Rails 4.0 to 4.1 Gives SASS-Rails Railties Version Conflicts
How to Ssh Interactive Session
How to Call a Method That Is a Hash Value
Ruby on Rails: Creating a Model Entry with a Belongs_To Association
What Are the Meanings of the Hash Keys When Calling Objectspace.Count_Objects
Generating a Race Condition with Mri
Using Watir to Check for Bad Links
Rails Reload Dynamic Routes on Multiple Instances/Servers
What's the Difference Between the Ruby Irb Prompt Modes
How to Simplify or Clean Up This Anagram Method
Why Is the << Operation on an Array in Ruby Not Atomic
Rails Activerecord Create or Find
How to Make a Ruby Enumerator That Does Lazy Iteration Through Two Other Enumerators