查找哪两种颜色混合形成第三种颜色的算法(在JavaScript中) [英] Algorithm to find which two colors mix to form a third color (in JavaScript)

查看:106
本文介绍了查找哪两种颜色混合形成第三种颜色的算法(在JavaScript中)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种采用三种加法或减法颜色并确定什么



代码中唯一重要的内容是 sb_rgbChange 事件,该事件在3个滚动条中的任何一个发生更改时都被调用。它为加性和减性逻辑计算 c1,c2 颜色并将颜色输出到面板中。



没问题...顺便说一句,您即使在我的 Random(x)正确的地方也会生成 x ,因此限制应为255 (我已经修复了答案)。



此处是完整的源代码( BDS2006 C ++ / VCL / Win32 )和Win32二进制文件:




I am looking for a library/algorithm/technique to take the 3 additive or subtractive colors and determine what combination of two results in some color x.

This is not a correct example (as I don't know much about color theory yet), but this is to illustrate the point. Say you have a color like greenish brown #45512b. The problem to solve is figure out -- for the two systems (additive and subtractive) -- the pair of colors that will generate greenish brown (the given color).

So you have the value "greenish brown" #45512b, and want to know what paints mix together to form this color. Maybe it is #fff123 and #bbb456 that combine subtractively to form greenish brown (just making this up). Then for additive mixing, figuring out the two shades of light of the 3 base colors of light used in computational models that combine to form greenish brown.

Basically just looking for this:

function additiveComponents(color) {
  return [ a, b ]
}

function subtractiveComponents(color) {
  return [ a, b ]
}

The input color doesn't need to be in hex format, any of the color spaces would work. But in the end I would like to convert the two output values back to a hex value.

One naive way I could imagine doing this is to take the reverse algorithm (algorithm to mix two colors into a third color), and try every combination of colors until you find the right one. But that would be super inefficient, wondering if there is a better way or standard technique.

解决方案

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)

  1. 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);
    

  2. 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)

  1. 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);
    

  2. 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:

这篇关于查找哪两种颜色混合形成第三种颜色的算法(在JavaScript中)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆