Nadesłany przez Tomasz Lubiński, 05 listopada 2007 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
HSV - C++/Unit1.cpp:
// Model HSV // www.algorytm.org // (c)2007 by Tomasz Lubinski //--------------------------------------------------------------------------- #include <vcl.h> #include "math.h" #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" #define MIN(a,b) ((a)<(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void HSV2RGB(float hue, float sat, float val, float &red, float &grn, float &blu) { int i; float f, p, q, t; if(val==0) {red=0; grn=0; val=0;} else{ hue/=60; i = floor(hue); f = hue-i; p = val*(1-sat); q = val*(1-(sat*f)); t = val*(1-(sat*(1-f))); if (i==0) {red=val; grn=t; blu=p;} else if (i==1) {red=q; grn=val; blu=p;} else if (i==2) {red=p; grn=val; blu=t;} else if (i==3) {red=p; grn=q; blu=val;} else if (i==4) {red=t; grn=p; blu=val;} else if (i==5) {red=val; grn=p; blu=q;} } } void RGB2HSV(float &hue, float &sat, float &val, float red, float grn, float blu){ float x, f, i; x = MIN(MIN(red, grn), blu); val = MAX(MAX(red, grn), blu); if (x == val){ hue = 0; sat = 0; } else { f = (red == x) ? grn-blu : ((grn == x) ? blu-red : red-grn); i = (red == x) ? 3 : ((grn == x) ? 5 : 1); hue = fmod((i-f/(val-x))*60, 360); sat = ((val-x)/val); } } void __fastcall TForm1::DrawArc(float x, float y, float r1, float s, float v, int shift) { float h, r, g, b, r2; float incr = 45 / r1; r2 = r1 / 3.0; for (float i=180; i<360; i+=incr) { h = fmod(i + shift, 360); HSV2RGB(h, s, v, r, g, b); Model->Canvas->Pixels[r1*cos(i*M_PI/180)+x][-r2*sin(i*M_PI/180)+y] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); } } void __fastcall TForm1::FillCircle(float x, float y, float maxr, int shift) { float h, s, v, r, g, b, r1, r2; float incr; for (float j=1; j<maxr; j++) { r1 = j; r2 = r1 / 3.0; s = j / (maxr); v = 1; incr = 45 / r1; for (float i=0; i<360; i+=incr) { h = fmod(i + shift, 360); HSV2RGB(h, s, v, r, g, b); Model->Canvas->Pixels[r1*cos(i*M_PI/180)+x][-r2*sin(i*M_PI/180)+y] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); } } } void __fastcall TForm1::Button1Click(TObject *Sender) { float h,s,v,r,g,b,step; int width, height, shift, shift_x, shift_y; float r1, r2; float incr; Model->Canvas->Brush->Color = clWhite; Model->Canvas->Rectangle(0, 0, Model->Width, Model->Height); width = StrToInt(Width->Text); height = StrToInt(Height->Text); shift = StrToInt(Shift->Text); shift_x = Model->Width / 2; shift_y = 50; step = (width*1.0)/height; for (float k=height-1; k>=0; k--) { s = 1.0 - (1 / (width - (step*k))); v = 1 - (k / height); DrawArc(shift_x, shift_y + k, width - (step*k), s, v, shift); } FillCircle(shift_x, shift_y, width, shift); //draw H, S and V crosses r1 = width; r2 = r1 / 3.0; shift_y -= 10; incr = 45 / r1; for (float i=0; i<270; i+=incr) { Model->Canvas->Pixels[r1*cos(i*M_PI/180)+shift_x][-r2*sin(i*M_PI/180)+shift_y] = (TColor)(int)0; } Model->Canvas->MoveTo(r1*cos(270*M_PI/180)+shift_x, -r2*sin(270*M_PI/180)+shift_y); Model->Canvas->LineTo(r1*cos(270*M_PI/180)+shift_x-5, -r2*sin(270*M_PI/180)+shift_y-5); Model->Canvas->MoveTo(r1*cos(270*M_PI/180)+shift_x, -r2*sin(270*M_PI/180)+shift_y); Model->Canvas->LineTo(r1*cos(270*M_PI/180)+shift_x-5, -r2*sin(270*M_PI/180)+shift_y+5); Model->Canvas->TextOutA(r1*cos(140*M_PI/180)+shift_x-30, -r2*sin(140*M_PI/180)+shift_y+5, "H"); Model->Canvas->MoveTo(shift_x - r1 - 10, shift_y + r2/2 + height); Model->Canvas->LineTo(shift_x - r1 - 10, shift_y + r2/2); Model->Canvas->LineTo(shift_x - r1 - 15, shift_y + r2/2 + 5); Model->Canvas->MoveTo(shift_x - r1 - 10, shift_y + r2/2); Model->Canvas->LineTo(shift_x - r1 - 5, shift_y + r2/2 + 5); Model->Canvas->TextOutA(shift_x - r1 - 20, shift_y + r2/2 + 15, "V"); Model->Canvas->MoveTo(shift_x, shift_y + r2/2 + height); Model->Canvas->LineTo(shift_x - r1, shift_y + r2/2 + height); Model->Canvas->LineTo(shift_x - r1 + 5, shift_y + r2/2 + height - 5); Model->Canvas->MoveTo(shift_x - r1, shift_y + r2/2 + height); Model->Canvas->LineTo(shift_x - r1 + 5, shift_y + r2/2 + height + 5); Model->Canvas->TextOutA(shift_x - r1 + 15, shift_y + r2/2 + height - 15, "S"); Model->Refresh(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { for (int i=0; i<=360; i+=10) { Shift->Text = IntToStr(i); Button1Click(Sender); } } //--------------------------------------------------------------------------- void __fastcall TForm1::HButtonClick(TObject *Sender) { ReDrawProbe(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::SButtonClick(TObject *Sender) { ReDrawProbe(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::VButtonClick(TObject *Sender) { ReDrawProbe(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::ReDrawProbe(TObject *Sender) { float h, s, v, r, g, b; h = StrToInt(H->Text); s = StrToInt(S->Text) / 100.0; v = StrToInt(V->Text) / 100.0; ProbeSmall->Canvas->Brush->Color = clWhite; ProbeSmall->Canvas->Rectangle(0, 0, ProbeSmall->Width, ProbeSmall->Height); if (HButton->Checked) { s = 1; v = 1; for (int i=0; i<256; i++) { h = (i * 359.0) / 255; HSV2RGB(h, s, v, r, g, b); ProbeSmall->Canvas->Pixels[1][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[2][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[3][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[4][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[5][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[6][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[7][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[8][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[9][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[10][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[11][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[12][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[13][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[14][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[15][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); } } else if (SButton->Checked) { for (int i=0; i<256; i++) { s = i / 255.0; HSV2RGB(h, s, v, r, g, b); ProbeSmall->Canvas->Pixels[1][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[2][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[3][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[4][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[5][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[6][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[7][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[8][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[9][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[10][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[11][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[12][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[13][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[14][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[15][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); } } else if (VButton->Checked) { for (int i=0; i<256; i++) { v = i / 255.0; HSV2RGB(h, s, v, r, g, b); ProbeSmall->Canvas->Pixels[1][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[2][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[3][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[4][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[5][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[6][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[7][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[8][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[9][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[10][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[11][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[12][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[13][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[14][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); ProbeSmall->Canvas->Pixels[15][i] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); } } h = StrToInt(H->Text); s = StrToInt(S->Text) / 100.0; v = StrToInt(V->Text) / 100.0; ProbeLarge->Canvas->Brush->Color = clWhite; ProbeLarge->Canvas->Rectangle(0, 0, ProbeLarge->Width, ProbeLarge->Height); if (HButton->Checked) { for (int i=0; i<256; i++) { for (int j=0; j<256; j++) { s = i / 255.0; v = j / 255.0; HSV2RGB(h, s, v, r, g, b); ProbeLarge->Canvas->Pixels[i][255-j] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); } } } else if (SButton->Checked) { for (int i=0; i<256; i++) { for (int j=0; j<256; j++) { h = (i * 359.0) / 255; v = j / 255.0; HSV2RGB(h, s, v, r, g, b); ProbeLarge->Canvas->Pixels[i][255-j] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); } } } else if (VButton->Checked) { for (int i=0; i<256; i++) { for (int j=0; j<256; j++) { h = (i * 359.0) / 255; s = j / 255.0; HSV2RGB(h, s, v, r, g, b); ProbeLarge->Canvas->Pixels[i][255-j] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); } } } ReDrawRectangle(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::ReDrawRectangle(TObject *Sender) { float h, s, v, r, g, b; h = StrToInt(H->Text); s = StrToInt(S->Text) / 100.0; v = StrToInt(V->Text) / 100.0; HSV2RGB(h, s, v, r, g, b); Probe->Canvas->Brush->Color = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); Probe->Canvas->Rectangle(0, 0, Probe->Width, Probe->Height); if (HButton->Checked) { ProbeSmall->Canvas->Ellipse(5, h*255/359-3, 13, h*255/359+3); ProbeLarge->Canvas->Ellipse(s*255-3, 255-v*255-3, s*255+3, 255-v*255+3); } else if (SButton->Checked) { ProbeSmall->Canvas->Ellipse(5, s*255-3, 13, s*255+3); ProbeLarge->Canvas->Ellipse(h*255/359-3, 255-v*255-3, h*255/359+3, 255-v*255+3); } else if (VButton->Checked) { ProbeSmall->Canvas->Ellipse(5, v*255-3, 13, v*255+3); ProbeLarge->Canvas->Ellipse(h*255/359-3, 255-s*255-3, h*255/359+3, 255-s*255+3); } } //--------------------------------------------------------------------------- void __fastcall TForm1::HChange(TObject *Sender) { ReDrawProbe(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::SChange(TObject *Sender) { ReDrawProbe(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::VChange(TObject *Sender) { ReDrawProbe(Sender); } //--------------------------------------------------------------------------- void __fastcall TForm1::ProbeLargeMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if (HButton->Checked) { S->Text = IntToStr((X*100)/255); V->Text = IntToStr(100-(Y*100)/255); } else if (SButton->Checked) { H->Text = IntToStr((X*359)/255); V->Text = IntToStr(100-(Y*100)/255); } else if (VButton->Checked) { H->Text = IntToStr((X*359)/255); S->Text = IntToStr(100-(Y*100)/255); } } //--------------------------------------------------------------------------- void __fastcall TForm1::ProbeSmallMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if (HButton->Checked) { H->Text = IntToStr((Y*359)/255); } else if (SButton->Checked) { S->Text = IntToStr((Y*100)/255); } else if (VButton->Checked) { V->Text = IntToStr((Y*100)/255); } } //--------------------------------------------------------------------------- void __fastcall TForm1::FormActivate(TObject *Sender) { ReDrawProbe(Sender); Button1Click(Sender); Layers(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Layers() { float r, g, b, h, s, v; TColor color; for (int i=0; i<AllLayers->Width; i++) { for (int j=0; j<AllLayers->Height; j++) { color = AllLayers->Canvas->Pixels[i][j]; r = (color & 0xFF) / 255.0; g = ((color & 0xFF00) >> 8) / 255.0; b = ((color & 0xFF0000) >> 16) / 255.0; RGB2HSV(h, s, v, r, g, b); HSV2RGB(h, 1, 1, r, g, b); LayerH->Canvas->Pixels[i][j] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); HSV2RGB(0, s, 1, r, g, b); LayerS->Canvas->Pixels[i][j] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); HSV2RGB(0, 0, v, r, g, b); LayerV->Canvas->Pixels[i][j] = (TColor)(int)(r*255) + ((int)(g*255) << 8) + ((int)(b*255) << 16); } } }