# Lacklustre LinearGradient Swatch • ### Question

• I am attempting to create an optically useful colour swatch. It should contain all the primary colours and blends of these in full saturation.

I tried defining various LinearGradient  brushes to do this, but I wasn't very happy with the result. Then I decided to create one mathematically by iterating HSL with constant Saturation and Luminosity components and returning RGB. This result lacks a proper blend too. I tried with up to 100,000 points... Same result. (The mathematical approach has the advantage that a slider can be calibrated to return RGB Html values from a hash table.)

I suspect that what I want to do is perfectly possible, but perhaps I am missing something obvious?

Here is a test example which utilises both methods.

To switch between the examples: Make line 63 look like the commented line 68 and then uncomment 73.

```Function HSL2RGB([double]\$h,[double]\$sl,[double]\$l)
{
[double]\$v,\$r,\$g,\$b,\$m,\$sv,\$fract,\$vsf,\$mid1,\$mid2;\$r=\$l;\$g=\$l;\$b=\$l
if (\$l-le0.5){\$v=\$l*(1.0+\$sl)}else{\$v=(\$l+\$sl-\$l*\$sl)}
if (\$v-gt0)
{
\$m = \$l + \$l - \$v
\$sv = (\$v - \$m ) / \$v
\$h = \$h * 6.0
[int]\$sextant = \$h
\$fract = \$h - \$sextant
\$vsf = \$v * \$sv * \$fract
\$mid1 = \$m + \$vsf
\$mid2 = \$v - \$vsf
switch (\$sextant)
{
0 {\$r=\$v;\$g=\$mid1;\$b=\$m;break}
1 {\$r=\$mid2;\$g=\$v;\$b=\$m;break}
2 {\$r=\$m;\$g=\$v;\$b=\$mid1;break}
3 {\$r=\$m;\$g=\$mid2;\$b=\$v;break}
4 {\$r=\$mid1;\$g=\$m;\$b=\$v;break}
5 {\$r=\$v;\$g=\$m;\$b=\$mid2;break}
}
}

\$rgb = [System.Drawing.Color]::FromArgb([byte]255,\$([Convert]::ToByte("{0:f0}" -f \$(\$r * 255))),\$([Convert]::ToByte("{0:f0}" -f \$(\$b * 255))),\$([Convert]::ToByte("{0:f0}" -f \$(\$g * 255))))
return \$rgb
}

Add-Type -AssemblyName PresentationFramework, PresentationCore, WindowsBase, System.Drawing

for([double]\$i = 0; \$i -lt 1; \$i+=0.01)
{
\$c = HSL2RGB \$i 0.5 0.5
}
\$Fill = [System.Windows.Media.LinearGradientBrush]::new(\$GS, \$(new-object Windows.Point @([double] 0, [double] 0)), \$(new-object Windows.Point @([double] 0, [double] 1)))

[xml]\$xaml = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="Test" Height="300" Width="100" SizeToContent="WidthAndHeight" WindowStyle="ThreeDBorderWindow" WindowStartupLocation="CenterOwner" ResizeMode="NoResize" Background="WhiteSmoke">
<Window.Resources>
</Window.Resources>
<Grid Background="White">
<Border x:Name="Border"  Background="{StaticResource Brush}" Width="30" Height="255" />
</Grid>
</Window>
"@

# <Border x:Name="Border" Width="30" Height="255" />

\$xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]")  |% {New-Variable  -Name \$_.Name -Value \$Form.FindName(\$_.Name) -Force}
#\$border.BackGround = \$Fill
[void]\$Form.ShowDialog()```

Many thanks for any help. Edit: If you think I should be posting this in a language agnostic forum, please point me.

• Edited by Thursday, February 21, 2019 2:37 PM Added redirection comment to another forum.
Thursday, February 21, 2019 2:16 PM

• 