Linearly interpolation
I once had the same need to do linearly interpolation
between two colors in a winform. I will do an exception and share the code behind this as I think it might be useful for not only the OP but others.
The function accept a Single
value in the range 0.0
(0%) to 1.0
(100%).
Public Shared Function Lerp(ByVal color1 As Color, ByVal color2 As Color, ByVal amount As Single) As Color
Const bitmask As Single = 65536.0!
Dim n As UInteger = CUInt(Math.Round(CDbl(Math.Max(Math.Min((amount * bitmask), bitmask), 0.0!))))
Dim r As Integer = (CInt(color1.R) + (((CInt(color2.R) - CInt(color1.R)) * CInt(n)) >> 16))
Dim g As Integer = (CInt(color1.G) + (((CInt(color2.G) - CInt(color1.G)) * CInt(n)) >> 16))
Dim b As Integer = (CInt(color1.B) + (((CInt(color2.B) - CInt(color1.B)) * CInt(n)) >> 16))
Dim a As Integer = (CInt(color1.A) + (((CInt(color2.A) - CInt(color1.A)) * CInt(n)) >> 16))
Return Color.FromArgb(a, r, g, b)
End Function
So in your case it will look like this:
Dim value As Integer = 'A value in the range 0 - 100
Dim newColor As Color = Lerp(Color.Red, Color.Green, If((value > 0I), (Math.Min(Math.Max(CSng(value), 0.0!), 100.0!) / 100.0!), 0.0!))
Luminosity
Regarding the part "white or black, depending on the background" you need to know the luminosity of the color. The following function returns 0 for a black and 240 for a white color. So if the luminosity of a given backcolor is <= 120
one should use a white forecolor.
Public Shared Function GetLuminosity(c As Color) As Integer
Return CInt((((Math.Max(Math.Max(CInt(c.R), CInt(c.G)), CInt(c.B)) + Math.Min(Math.Min(CInt(c.R), CInt(c.G)), CInt(c.B))) * 240) + 255) / 510I)
End Function