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);
}
}
}

