I'm working on a Delphi FMX project where I need to generate a set of 10 random colors for use in a UI. The problem is that when I use TAlphaColorRec
with random RGB values, many of the colors end up looking too similar.
For example, multiple shades of blue or green that are hard to tell apart.
This is my current code that generates the numbers:
function GenerateRandomColors(Count: UInt64): TArray<TAlphaColor>;
begin
SetLength(Result, Count);
for var i := 1 to Count do
begin
var C: TAlphaColorRec;
C.R := Random(256);
C.G := Random(256);
C.B := Random(256);
C.A := 255;
Result[i-1] := C.Color;
end;
end;
And I'm using it within this procedure:
procedure TForm1.GenerateColors;
begin
Randomize;
Memo1.Lines.Clear;
GridLayout1.DeleteChildren;
var Colors := GenerateRandomColors(10);
for var Col in Colors do
begin
Memo1.Lines.Add(AlphaColorToString(Col));
var Rect := TRectangle.Create(GridLayout1);
Rect.Parent := GridLayout1;
Rect.Fill.Color := Col;
Rect.Stroke.Kind := TBrushKind.None;
end;
end;
And this is how it looks:
I need to modify GenerateRandomColors
so that it generates colors that are more visually distinct from each other.
I have looked at the following questions already:
But the answers are not super useful because I need it to work with the Delphi Programming Language and most of those answers are using other programming languages.
Can someone please help me to modify GenerateRandomColors
so that it generates distinct colors using Delphi within the FireMonkey (FMX) framework.
Thanks skamradt for pointing me in the right direction. This is the function I ended up making and using:
uses
System.UIConsts;
function GenerateRandomDistinctColors(Count: UInt64): TArray<TAlphaColor>;
begin
SetLength(Result, Count);
if Count = 0 then Exit;
var reserved := 0;
if Count > 0 then
begin
Result[reserved] := TAlphaColors.Black;
Inc(reserved);
end;
if Count > 1 then
begin
Result[reserved] := TAlphaColors.White;
Inc(reserved);
end;
if Count > 2 then
begin
Result[reserved] := TAlphaColors.Gray;
Inc(reserved);
end;
var remain := Count - reserved;
if remain <= 0 then Exit;
var baseHue := Random * 360.0;
var stepHue := 360.0 / remain;
var j := 0;
while j < remain do
begin
var hue := baseHue + j * stepHue + (Random * 2.0 - 1.0) * (stepHue * 0.08);
hue := Frac(hue / 360.0) * 360.0;
var sat := 0.6 + Random * 0.4; // 0.6..1.0
var light := 0.45 + Random * 0.2; // 0.45..0.65
Result[reserved + j] := HSLtoRGB(hue / 360.0, sat, light);
Inc(j);
end;
end;
It works similar to this answer, but modified to provide a slightly wider ranger of colors.
Here's an example of the colors it generated:
They are now much more distinct from each other. š