Page 1 of 1
RGB Rainbow colours
Posted: Fri Jan 12, 2024 10:38 pm
by matalog
I use this method of mixing colours to get decent gradients of most colours, but I noticed it's far from perfect cycling of all colours. There is very little red in the mix and no noticable yellow.
Any tips to get a better mix of all colours, or even a more balanced traditional set of rainbow colours?
Code: Select all
#width=1800
#height=900
OpenWindow(0,0,0,#width,#height,"Window")
CreateImage(0,#width,#height)
ImageGadget(0,0,0,#width,#height,ImageID(0))
StartDrawing(ImageOutput(0))
Global.i r,g,b
Box(0,0,#width,#height,#Black)
For x=0 To #width-1
r=128+Round((128-0.5)*Sin((2*#PI)/#width*x+(2*#PI)/360*0),#PB_Round_Down)
g=128+Round((128-0.5)*Sin((2*#PI)/#width*x+(2*#PI)/360*120),#PB_Round_Down)
b=128+Round((128-0.5)*Sin((2*#PI)/#width*x+(2*#PI)/360*240),#PB_Round_Down)
Line(x,0,1,#height-700,RGB(r,g,b))
Circle(x,500-r,10,#Red)
Circle(x,500-g,10,#Green)
Circle(x,500-b,10,#Blue)
Next
StopDrawing()
SetGadgetState(0,ImageID(0))
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_Gadget
If EventGadget() = 0
End
EndIf
Case #PB_Event_CloseWindow
End
EndSelect
Until Event = 0
Until Event = #PB_Event_CloseWindow
Re: RGB Rainbow colours
Posted: Sat Jan 13, 2024 6:20 pm
by STARGÅTE
You can try to use HSV(Hue, Saturation, Value):
Code: Select all
Procedure.l HSV(Hue.f, Saturation.f, Value.f)
Protected H.i = Int(Hue/60)
Protected f.f = (Hue/60-H)
Protected S.f = Saturation/100
If S > 1.0 : S = 1.0 : ElseIf S < 0.0 : S = 0.0 : EndIf
Protected V.f = Value * 2.55
If V > 255 : V = 255 : ElseIf V < 0 : V = 0 : EndIf
Protected p.i = V * (1-S)
Protected q.i = V * (1-S*f)
Protected t.i = V * (1-S*(1-f))
Select H
Case 1 : ProcedureReturn RGB(q,V,p)
Case 2 : ProcedureReturn RGB(p,V,t)
Case 3 : ProcedureReturn RGB(p,q,V)
Case 4 : ProcedureReturn RGB(t,p,V)
Case 5 : ProcedureReturn RGB(V,p,q)
Default : ProcedureReturn RGB(V,t,p)
EndSelect
EndProcedure
Code: Select all
#width=1800
#height=900
OpenWindow(0,0,0,#width,#height,"Window")
CreateImage(0,#width,#height)
ImageGadget(0,0,0,#width,#height,ImageID(0))
StartDrawing(ImageOutput(0))
Global.i r,g,b
Box(0,0,#width,#height,#Black)
For x=0 To #width-1
r=Red(HSV(360*x/#width, 100, 255))
g=Green(HSV(360*x/#width, 100, 255))
b=Blue(HSV(360*x/#width, 100, 255))
Line(x,0,1,#height-700,RGB(r,g,b))
Circle(x,500-r,10,#Red)
Circle(x,500-g,10,#Green)
Circle(x,500-b,10,#Blue)
Next
StopDrawing()
SetGadgetState(0,ImageID(0))
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_Gadget
If EventGadget() = 0
End
EndIf
Case #PB_Event_CloseWindow
End
EndSelect
Until Event = 0
Until Event = #PB_Event_CloseWindow
However, if you really want the "rainbow colors", in the sense of wavelength and color, this topic becomes more complicated:
https://en.wikipedia.org/wiki/Color_model
Re: RGB Rainbow colours
Posted: Sat Jan 13, 2024 11:27 pm
by matalog
That is definitely a lot more balanced, thanks for sharing it. The gradients don't seem so smooth around the peaks at Yellow, Cyan and Magenta though.
Re: RGB Rainbow colours
Posted: Sat Jan 13, 2024 11:50 pm
by STARGÅTE
Try:
Code: Select all
Procedure.l HSV(Hue.f, Saturation.f, Value.f)
Protected H.i = Int(Hue/60)
Protected f.f = 1-Pow(Cos((Hue/60-H)*#PI/2), 2)
Protected S.f = Saturation/100
If S > 1.0 : S = 1.0 : ElseIf S < 0.0 : S = 0.0 : EndIf
Protected V.f = Value * 2.55
If V > 255 : V = 255 : ElseIf V < 0 : V = 0 : EndIf
Protected p.i = V * (1-S)
Protected q.i = V * (1-S*f)
Protected t.i = V * (1-S*(1-f))
Select H
Case 1 : ProcedureReturn RGB(q,V,p)
Case 2 : ProcedureReturn RGB(p,V,t)
Case 3 : ProcedureReturn RGB(p,q,V)
Case 4 : ProcedureReturn RGB(t,p,V)
Case 5 : ProcedureReturn RGB(V,p,q)
Default : ProcedureReturn RGB(V,t,p)
EndSelect
EndProcedure
Re: RGB Rainbow colours
Posted: Sun Jan 14, 2024 12:25 am
by matalog
Yeah, that's great, much better. For me, the range of colours is perfect, it is just a tiny bit not smooth enough in the very centre of the 3 colours I mentioned.
I probably started this, but if we anyone is leaving this open for a long time, then change line 44 to
instead of
Re: RGB Rainbow colours
Posted: Sun Jan 14, 2024 8:16 am
by AZJIO
Code: Select all
Global Dim arr_rgb(2)
Global Dim arr_hsb(2)
Procedure hsb_to_rgb()
Protected sector
Protected.f ff, pp, qq, tt
Protected.f Dim af_rgb(2) ; создаём массивы в которых числа будут в диапазоне 0-1
Protected.f Dim af_hsb(2)
; Protected Dim arr_rgb(2)
af_hsb(2) = arr_hsb(2) / 100
If arr_hsb(1) = 0 ; если серый, то одно значение всем
arr_rgb(0) = Round(af_hsb(2) * 255, #PB_Round_Nearest)
arr_rgb(1) = arr_rgb(0)
arr_rgb(2) = arr_rgb(0)
; ProcedureReturn arr_rgb
EndIf
While arr_hsb(0) >= 360 ; если тон задан большим запредельным числом, то
arr_hsb(0) - 360
Wend
af_hsb(1) = arr_hsb(1) / 100
af_hsb(0) = arr_hsb(0) / 60
; sector = Int(arr_hsb(0))
sector = Round(af_hsb(0), #PB_Round_Down)
ff = af_hsb(0) - sector
pp = af_hsb(2) * (1 - af_hsb(1))
qq = af_hsb(2) * (1 - af_hsb(1) * ff)
tt = af_hsb(2) * (1 - af_hsb(1) * (1 - ff))
Select sector
Case 0
af_rgb(0) = af_hsb(2)
af_rgb(1) = tt
af_rgb(2) = pp
Case 1
af_rgb(0) = qq
af_rgb(1) = af_hsb(2)
af_rgb(2) = pp
Case 2
af_rgb(0) = pp
af_rgb(1) = af_hsb(2)
af_rgb(2) = tt
Case 3
af_rgb(0) = pp
af_rgb(1) = qq
af_rgb(2) = af_hsb(2)
Case 4
af_rgb(0) = tt
af_rgb(1) = pp
af_rgb(2) = af_hsb(2)
Default
af_rgb(0) = af_hsb(2)
af_rgb(1) = pp
af_rgb(2) = qq
EndSelect
; RGB
arr_rgb(0) = Round(af_rgb(0) * 255, #PB_Round_Nearest)
arr_rgb(1) = Round(af_rgb(1) * 255, #PB_Round_Nearest)
arr_rgb(2) = Round(af_rgb(2) * 255, #PB_Round_Nearest)
; BGR
; arr_rgb(2)=Round(af_rgb(0)*255, #PB_Round_Nearest)
; arr_rgb(1)=Round(af_rgb(1)*255, #PB_Round_Nearest)
; arr_rgb(0)=Round(af_rgb(2)*255, #PB_Round_Nearest)
; ProcedureReturn arr_rgb
EndProcedure
#width = 1275
#height = 900
OpenWindow(0, 0, 0, #width, #height, "Window")
CreateImage(0, #width, #height)
ImageGadget(0, 0, 0, #width, #height, ImageID(0))
StartDrawing(ImageOutput(0))
Global.i r, g, b, z
arr_hsb(1) = 100
arr_hsb(2) = 100
Box(0, 0, #width, #height, #Black)
For x = 0 To #width - 1
; arr_hsb(0) = 360 * x / #width
arr_hsb(0) = 360 * x / #width + 100
; smoothing (delete if not needed)
; darkening bright areas
z = arr_hsb(0) % 60
If z > 30
z = Abs(z - 60)
EndIf
; arr_hsb(2) = 70 + z
arr_hsb(2) = 85 + z/2
; arr_hsb(2) = 90 + z/3
; Lightening dark parts
z = (arr_hsb(0) + 0) % 60
If z > 30
z = Abs(z - 60)
EndIf
arr_hsb(1) = 70 + z
; Debug arr_hsb(1)
; the end of smoothing
hsb_to_rgb()
; Line(x, 0, 1, #height - 700, RGB(arr_rgb(0), arr_rgb(1), arr_rgb(2)))
Line(#width - x, 0, 1, #height - 700, RGB(arr_rgb(0), arr_rgb(1), arr_rgb(2)))
Circle(x * 3.5, Sin(Radian(x) + Radian(180)) * 120 + 500, 10, #Red)
Circle(x * 3.5, Sin(Radian(x) + Radian(300)) * 120 + 500, 10, #Green)
Circle(x * 3.5, Sin(Radian(x) + Radian(60)) * 120 + 500, 10, #Blue)
Next
StopDrawing()
SetGadgetState(0, ImageID(0))
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_Gadget
If EventGadget() = 0
End
EndIf
Case #PB_Event_CloseWindow
End
EndSelect
Until Event = 0
Until Event = #PB_Event_CloseWindow
Re: RGB Rainbow colours
Posted: Sun Jan 14, 2024 8:27 pm
by Olli
Let's imagine,
x is the red color;
y is the green color, and
z is the blue color.
What you would need is a cube cut in two parts. The triangle drawn by this cut, goes through the three sides : red, green and blue.