Mieszanie kolorów, trójkąt Maxwella
(myszą możesz zmieniać punkty R, B i G)Najpierw wywołamy wrażenie emisji trzech źródeł światła R, G i B.
Algorytm rysujący trójkąt Sierpińskiego, może nam być tutaj pomocny.
Jeden wędrujący punkt losowo wybiera wierzchołek trójkąta i zajmuje nową pozycję w wyskalowanej dległości od niego.
Uzyskamy dwa efekty :
1° pracę "jednego fotonu"
2° zamkniemy wędrówkę punktu wewnątrz Δ RGB.
W trakcie swojej wędrówki nasz punkt będzie podejmował decyzje o swoim kolorze, tak jak to przedstawiono w aplecie po lewej stronie.
Najbardziej znany efekt to tzw trójkąt Maxwella i nim zajmiemy się szczegółowo:
//---deklaracje zmiennych------------ pkt2d w[ ]=new pkt2d[3]; pkt2d b; int pal[ ]=new int[3]; //---Wierzchołki RGB,punkt i kolory-- public void init( ) { w[0]=new pkt2d(-7,-4); w[1]=new pkt2d(-1,6); w[2]=new pkt2d(7,-5); b=new pkt2d(0,0); pal[0]=0xff0000; pal[1]=0x00ff00; pal[2]=0x0000ff; } |
void swiatlo(Graphics g) {int los,kolor; for(int i=0;i<1500;i++) { los=mat.losowa_c(n); b.x=b.x+(w[los].x-b.x)/5.0; b.y=b.y+(w[los].y-b.y)/5.0; kolor=maxwella(b); g.setColor(kolor); lo28.punkt(g,b); } } |
ρ(b,GB) |
kolor=new Color(r/d, g/d, b/d); |
Jeszcze słowo o odległości np ρ(b,GB) lub ρ(R,GB).
Rozwiążmy problem ogólny tzn wyznaczymy funkcję odl liczącą odległość punktu p od prostej pr(a,b).
Najpierw ustalimy wzór prostej w postaci normalnej : Ax+By+C=0
v=[v.x,v.y]=[b.x-a.x, b.y-a.y] to wektor kierunkowy (równoległy) prostej.
Nas interesuje wektor normalny [A,B]=[-v.y,v.x]
. Ostatecznie
To tyle matematyki, teraz kod funkcji odl i maxwella:
float odl(pkt2d p,pkt2d a,pkt2d b) {float A,B,C,l,m; A=(float)(-b.y+a.y); B=(float)(b.x-a.x); C=(float)(-A*a.x-B*a.y); l=(float)Math.abs(A*p.x+B*p.y+C); m=(float)Math.sqrt(A*A+B*B); return(l/m); } |
Color maxwella(pkt2d p) { float dr=odl(p,w[1],w[2]); float dg=odl(p,w[0],w[2]); float db=odl(p,w[0],w[1]); float r=dr/ro_r; float g=dg/ro_g; float b=db/ro_b; float d=Max(r,g,b); return(new Color(r/d,g/d,b/d)); } |
ro_r=odl(w[0],w[1],w[2]); ro_g=odl(w[1],w[0],w[2]); ro_b=odl(w[2],w[0],w[1]); |
BRAK | AND | PLUS |
---|---|---|
kolor=new Color(pal[los]) | kolor=new Color(pal[los] | getKolor(b)) | kolor=new Color(pal[los]+getKolor(b)) |