use RGB color model. I am assuming you got 8 bit per channel color c0=(r0,g0,b0)
and want to know c1,c2
that mix back to c0
.
Additive mixing (light sources)
chose one color c1
to be able to mix up to c0
the c1
must be less or equal to c0
on per channel bases. So for example random lesser color:
r1 = Random(r0);
g1 = Random(g0);
b1 = Random(b0);
compute the missing color c2
simply use the additive logic:
c0 = c1 + c2
so
c2 = c0 - c1
r2 = r0 - r1
g2 = g0 - g1
b2 = b0 - b1
Substractive mixing (filters, paint colors)
chose one color c1
this time c1
must be c1>=c0
so again random such color example:
r1 = r0 + Random(255-r0);
g1 = g0 + Random(255-g0);
b1 = b0 + Random(255-b0);
compute the missing color c2
simply use the substractive logic:
c0 = c1 - c2
so
c2 = c1 - c0
r2 = r1 - r0
g2 = g1 - g0
b2 = b1 - b0
[Edit1] example
I just encoded a simple C++/VCL app to test this. So I got 3 sscrollbars to chose RGB of target color c0
and then some panels to show the c1,c2
and their mix to visually verify its working as should. Here the code:
//$$---- Form CPP ----
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "win_main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
const int _r=0; // channel order
const int _g=1;
const int _b=2;
const int _a=3;
union color
{
BYTE db[4]; // channel access
DWORD dd; // all 32 bit of color
TColor c; // VCL/GDI color (you can ignore this)
};
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
{
sb_rgbChange(this);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::sb_rgbChange(TObject *Sender)
{
int i;
color c0,c1,c2,c;
Randomize();
// get c0 color from R,G,B sliders
c0.db[_r]=255-sb_r->Position;
c0.db[_g]=255-sb_g->Position;
c0.db[_b]=255-sb_b->Position;
c0.db[_a]=0;
pan_c0->Color=c0.c; // just show color on some panel
// additive
for (i=0;i<3;i++) c1.db[i]=Random(c0.db[i]); c1.db[_a]=0; // generate c1 <= c0
for (i=0;i<3;i++) c2.db[i]=c0.db[i]-c1.db[i]; c2.db[_a]=0; // compute c2 = c0 - c1
for (i=0;i<3;i++) c.db[i]=c1.db[i]+c2.db[i]; c.db[_a]=0; // verify c = c1 + c2
pan_add_c1->Color=c1.c; // just show colors on some panels
pan_add_c2->Color=c2.c;
pan_add_c ->Color= c.c;
// substractive
for (i=0;i<3;i++) c1.db[i]=c0.db[i]+Random(255-c0.db[i]); c1.db[_a]=0; // generate c1 >= c0
for (i=0;i<3;i++) c2.db[i]=c1.db[i]-c0.db[i]; c2.db[_a]=0; // compute c2 = c1 - c0
for (i=0;i<3;i++) c.db[i]=c1.db[i]-c2.db[i]; c.db[_a]=0; // verify c = c1 - c2
pan_sub_c1->Color=c1.c; // just show colors on some panels
pan_sub_c2->Color=c2.c;
pan_sub_c ->Color= c.c;
}
//---------------------------------------------------------------------------
And here a screenshot:
The only important stuff in code is the sb_rgbChange
event which is called on any change of any of the 3 scrollbars. It compute the c1,c2
colors for both additive and substractive logic and output the colors into pannels.
It works without any problem... btw You where right even my Random(x)
generates x
so the limit should be 255 (I already repaired the answer).
Here complete source code (BDS2006 C++/VCL/Win32) and Win32 binary: