Skip to content

Instantly share code, notes, and snippets.

@hirosof
Created October 28, 2012 09:30
Show Gist options
  • Select an option

  • Save hirosof/3968158 to your computer and use it in GitHub Desktop.

Select an option

Save hirosof/3968158 to your computer and use it in GitHub Desktop.
#include "CHSLine.h"
#ifndef _CHSLine_CPP_
#define _CHSLine_CPP_
//コンストラクタ
CHSLine::CHSLine(void){
this->hdc = 0;
this->SetColor(0);
this->SetPosition(0,0);
}
CHSLine::CHSLine(HDC hdc){
this->hdc = hdc;
this->SetColor(0);
this->SetPosition(0,0);
}
//デバイスコンテキスト設定
HDC CHSLine::SetDC(HDC hdc){
HDC old_hdc = this->hdc;
this->hdc = hdc;
return old_hdc;
}
//現在選択されているデバイスコンテキストを取得
HDC CHSLine::GetDC(void){
return this->hdc;
}
void CHSLine::SetColor(int r , int g , int b){
r = min(255,max(0,r));
g = min(255,max(0,g));
b = min(255,max(0,b));
this->SetColor(RGB(r,g,b));
}
void CHSLine::SetColor(COLORREF rgb){
this->color[0] = (rgb & 0x0000FF) / 255.0;
this->color[1] = ((rgb & 0x00FF00) >> 8) / 255.0;
this->color[2] = ((rgb & 0xFF0000) >> 16) / 255.0;
}
COLORREF CHSLine::GetColor(void){
return RGB((float)(this->color[0] * 255.0),(float)(this->color[1]*255.0),(float)(this->color[2]*255.0));
}
void CHSLine::GetColor(int *pr , int *pg ,int *pb){
if(pr)*pr = (int)(float)(this->color[0] * 255.0);
if(pg)*pg = (int)(float)(this->color[1] * 255.0);
if(pb)*pb = (int)(float)(this->color[2] * 255.0);
}
void CHSLine::SetPosition(int x,int y){
this->pos.x = x;
this->pos.y = y;
}
void CHSLine::SetPosition(POINT pos){
this->pos = pos;
}
POINT CHSLine::GetPosition(void){
return this->pos;
}
void CHSLine::SetPositionX(int x){
this->pos.x = x;
}
void CHSLine::SetPositionY(int y){
this->pos.y = y;
}
int CHSLine::GetPositionX(void){
return this->pos.x;
}
int CHSLine::GetPositionY(void){
return this->pos.y;
}
void CHSLine::DrawEx(int start_x ,int start_y,int end_x , int end_y , BOOL SetPosFromEndPos){
int upper[2] = { 1,1 } , delta[2] = { 0 , 0};
int xyflag = 0 , namera=0;
delta[0] = end_x - start_x;
delta[1] = end_y - start_y;
int xy[2] ={ start_x , start_y};
for(int i = 0 ; i < 2 ; i++){
if(delta[i] < 0){
upper[i] = -1;
delta[i] *= -1;
}
}
if( delta[0] <= delta[1]) xyflag = 1;
for(int idx = 0 ; idx < (delta[xyflag] + 1) ; idx++){
SetPixel(this->hdc , xy[0] , xy[1] , this->GetColor());
xy[xyflag]+=upper[xyflag];
namera += delta[!xyflag];
if(namera >= delta[xyflag]){
namera -= delta[xyflag];
xy[!xyflag]+=upper[!xyflag];
}
}
if(SetPosFromEndPos) this->SetPosition(end_x , end_y);
}
void CHSLine::DrawEx(POINT start,POINT end_pos,BOOL SetPosFromEndPos ){
this->DrawEx(start.x,start.y,end_pos.x,end_pos.y,SetPosFromEndPos);
}
void CHSLine::Draw(int end_x , int end_y , BOOL SetPosFromEndPos){
POINT end_xy = { end_x , end_y };
this->Draw(end_xy,SetPosFromEndPos);
}
void CHSLine::Draw(POINT end_pos , BOOL SetPosFromEndPos){
this->DrawEx(this->pos,end_pos,SetPosFromEndPos);
}
BOOL CHSLine::DrawMultiPoint(LPPOINT lppoints,int num,BOOL SetPosFromEndPos){
return this->DrawMultiPointEx(lppoints,num,FALSE,SetPosFromEndPos);
}
BOOL CHSLine::DrawMultiPointEx(LPPOINT lppoints,int num,BOOL StartOfCurrentPos,BOOL SetPosFromEndPos){
POINT old_point;
if(!lppoints)return FALSE;
if(!((num>=2 && StartOfCurrentPos == FALSE)||(num>=1 && StartOfCurrentPos)))return FALSE;
old_point = this->GetPosition();
if(!StartOfCurrentPos){
this->SetPosition(*lppoints);
lppoints++;
num--;
}
for(int i= 0 ; i < num ; i++){
this->Draw(*lppoints);
lppoints++;
}
if(!SetPosFromEndPos)this->SetPosition(old_point);
return TRUE;
}
double CHSLine::max3(double num1,double num2,double num3){
double n;
n = (num1 > num2) ? num1 : num2 ;
return (n > num3) ? n : num3;
}
double CHSLine::min3(double num1,double num2,double num3){
double n;
n = (num1 < num2) ? num1 : num2 ;
return (n < num3) ? n : num3;
}
void CHSLine::ConvertRGBtoHSV(LPCHSLine_Color lpcolor){
double rgb[3],hsv[3];
double minval,maxval;
if(!lpcolor)return;
//RGBの値を構造体内共用体から取得
switch(lpcolor->rgbflag){
case CHSLC_USECOLORREF:
rgb[0] = (lpcolor->rgb & 0x0000FF) / 255.0;
rgb[1] = ((lpcolor->rgb & 0x00FF00) >> 8) / 255.0;
rgb[2] = ((lpcolor->rgb & 0xFF0000) >> 16) / 255.0;
break;
case CHSLC_8BIT_RGB:
rgb[0] = lpcolor->_8bitRGB.R / 255.0;
rgb[1] = lpcolor->_8bitRGB.G / 255.0;
rgb[2] = lpcolor->_8bitRGB.B / 255.0;
break;
case CHSLC_64BIT_FLOATRGB:
rgb[0] = lpcolor->_64bitfloatRGB.R;
rgb[1] = lpcolor->_64bitfloatRGB.G;
rgb[2] = lpcolor->_64bitfloatRGB.B;
break;
}
/*
最小値と最大値を取得
*/
minval = min3(rgb[0],rgb[1],rgb[2]);
maxval = max3(rgb[0],rgb[1],rgb[2]);
/*
最大値 = Vの値
*/
hsv[2] = maxval;
/*
Hの値を計算
*/
if(minval == maxval){
//最小値と最大値が等しい場合Hは定義されない。
hsv[0]=0.0;
}else{
//Rが最大の時60×(G-B)÷(最大値-最小値)+0
if(maxval==rgb[0])hsv[0]=60.0*(rgb[1]-rgb[2])/(maxval-minval);
//Gが最大の時60×(B-R)÷(最大値-最小値)+120
else if(maxval==rgb[1])hsv[0]=60.0*(rgb[2]-rgb[0])/(maxval-minval)+120;
//Bが最大の時60×(R-G)÷(最大値-最小値)+240
else hsv[0]=60.0*(rgb[0]-rgb[1])/(maxval-minval)+240;
//上の計算でマイナス値になった場合360.0を加算
if(hsv[0] <0)hsv[0]+=360.0;
}
/*
Sの値を計算
*/
if(maxval==0)hsv[1]=0;//最大値が0の場合Sは未定義
else hsv[1]=(maxval-minval)/maxval;
/*
結果を代入
*/
lpcolor->HSV.H = hsv[0];
lpcolor->HSV.S = hsv[1];
lpcolor->HSV.V = hsv[2];
}
void CHSLine::GetColorHSV(double *ph , double *ps , double *pv){
CHSLine_Color color;
color.rgbflag = CHSLC_64BIT_FLOATRGB;
memcpy( &color._64bitfloatRGB , this->color , sizeof(this->color) );
this->ConvertRGBtoHSV(&color);
if(ph)*ph = color.HSV.H;
if(ps)*ps = color.HSV.S;
if(pv)*pv = color.HSV.V;
}
void CHSLine::ConvertHSVtoRGB(LPCHSLine_Color lpcolor){
int hi;
double f,p,q,t,fr,fg,fb;
double H,S,V;
if(!lpcolor)return;
lpcolor->HSV.H = fmod(lpcolor->HSV.H , 360);
if(lpcolor->HSV.S == 0){
//S = 0 のとき R = G = B = 255(1.0);
fr = fg = fb = lpcolor->HSV.V;
}else{
H = lpcolor->HSV.H;
S = lpcolor->HSV.S;
V = lpcolor->HSV.V;
hi=((int)(H/60.0))%6;
f=H/60.0-hi;
p = V * (1 - S);
q = V * (1 - f*S);
t = V * (1 - (1 - f)*S);
switch(hi){
case 0:
fr = V ; fg = t ; fb = p;
break;
case 1:
fr = q ; fg = V ; fb = p;
break;
case 2:
fr = p ; fg = V ; fb = t;
break;
case 3:
fr = p ; fg = q ; fb = V;
break;
case 4:
fr = t ; fg = p ; fb = V;
break;
case 5:
fr = V ; fg = p ; fb = q;
break;
}
}
switch(lpcolor->rgbflag){
case CHSLC_USECOLORREF:
lpcolor->rgb = RGB((float)(fr * 255) , (float)(fg * 255) , (float)(fb * 255));
break;
case CHSLC_8BIT_RGB:
lpcolor->_8bitRGB.R = (unsigned __int8)(float)(fr * 255);
lpcolor->_8bitRGB.G = (unsigned __int8)(float)(fg * 255);
lpcolor->_8bitRGB.B = (unsigned __int8)(float)(fb * 255);
break;
case CHSLC_64BIT_FLOATRGB:
lpcolor->_64bitfloatRGB.R = fr;
lpcolor->_64bitfloatRGB.G = fg;
lpcolor->_64bitfloatRGB.B = fb;
break;
}
}
void CHSLine::SetColorHSV(double h , double s , double v){
CHSLine_Color color;
color.rgbflag = CHSLC_USECOLORREF;
color.HSV.H = h;
color.HSV.S = s;
color.HSV.V = v;
this->ConvertHSVtoRGB(&color);
this->SetColor(color.rgb);
}
BOOL CHSLine::DrawSize(int size_x , int size_y , BOOL SetPosFromEndPos){
int endx , endy;
if((size_x == 0) || (size_y == 0))return FALSE;
endx = this->GetPositionX() + size_x;
endy = this->GetPositionY() + size_y;
if(endx < this->GetPositionX())endx++;
else endx--;
if(endy < this->GetPositionY())endy++;
else endy--;
this->Draw(endx,endy , SetPosFromEndPos);
return TRUE;
}
BOOL CHSLine::DrawSize(SIZE size , BOOL SetPosFromEndPos){
return this->DrawSize(size.cx , size.cy , SetPosFromEndPos);
}
BOOL CHSLine::DrawExSize(int start_x,int start_y,int size_x,int size_y,BOOL SetPosFromEndPos){
POINT nowpt;
BOOL ret;
nowpt = this->GetPosition();
this->SetPosition(start_x , start_y);
ret = this->DrawSize(size_x,size_y,SetPosFromEndPos);
if(!SetPosFromEndPos)this->SetPosition(nowpt);
return ret;
}
BOOL CHSLine::DrawExSize(POINT start,SIZE size ,BOOL SetPosFromEndPos){
return this->DrawExSize(start.x , start.y , size.cx , size.cy , SetPosFromEndPos);
}
void CHSLine::SetColorR(int r){
this->color[0] = min(255,max(0,r)) / 255.0;
}
void CHSLine::SetColorG(int g){
this->color[1] = min(255,max(0,g)) / 255.0;
}
void CHSLine::SetColorB(int b){
this->color[2] = min(255,max(0,b)) / 255.0;
}
void CHSLine::SetColorH(double h){
double hsv[3];
this->GetColorHSV(hsv , hsv + 1 , hsv + 2);
hsv[0] = fmod(h,360);
this->SetColorHSV(hsv[0],hsv[1],hsv[2]);
}
void CHSLine::SetColorS(double s){
double hsv[3];
this->GetColorHSV(hsv , hsv + 1 , hsv + 2);
hsv[1] = min(1,max(s,0));
this->SetColorHSV(hsv[0],hsv[1],hsv[2]);
}
void CHSLine::SetColorV(double v){
double hsv[3];
this->GetColorHSV(hsv , hsv + 1 , hsv + 2);
hsv[2] = min(1,max(v,0));
this->SetColorHSV(hsv[0],hsv[1],hsv[2]);
}
int CHSLine::GetColorR(void){
int R;
this->GetColor(&R,NULL,NULL);
return R;
}
int CHSLine::GetColorG(void){
int G;
this->GetColor(NULL,&G,NULL);
return G;
}
int CHSLine::GetColorB(void){
int B;
this->GetColor(NULL,NULL,&B);
return B;
}
double CHSLine::GetColorH(void){
double H;
this->GetColorHSV(&H , NULL , NULL);
return H;
}
double CHSLine::GetColorS(void){
double S;
this->GetColorHSV(NULL , &S , NULL);
return S;
}
double CHSLine::GetColorV(void){
double V;
this->GetColorHSV(NULL, NULL , &V);
return V;
}
#endif
#include <Windows.h>
#include <math.h>
#ifndef _CHSLine_H_
#define _CHSLine_H_
enum CHSLine_ColorRGBFlag{
CHSLC_USECOLORREF,
CHSLC_8BIT_RGB,
CHSLC_64BIT_FLOATRGB
};
typedef struct tagCHSLine_Color{
CHSLine_ColorRGBFlag rgbflag;
union{
COLORREF rgb;
struct{
unsigned __int8 R;
unsigned __int8 G;
unsigned __int8 B;
operator int(void){
return R | G << 8 | B << 16;
}
void operator = (int value){
//0x00RRGGBB
//0xYYBBGGRR
if(value & 0xFF000000){
//0xBBGGRR
R = value & 0xFF;
G = (value & 0xFF00) >> 8;
B = (value & 0xFF0000) >> 16;
}else{
//0xRRGGBB
R = (value & 0xFF0000) >> 16;
G = (value & 0xFF00) >> 8;
B = value & 0xFF;
}
}
}_8bitRGB;
struct{
double R;
double G;
double B;
}_64bitfloatRGB;
};
struct{
double H;
double S;
double V;
}HSV;
}CHSLine_Color,*PCHSLine_Color,*LPCHSLine_Color;
class CHSLine{
private: //プライベート変数
HDC hdc; //デバイスコンテキストハンドル
POINT pos; //現在の位置
double color[3]; //線の色(RGB、ただし0.0~1.0)
protected: //内部使用関数
void ConvertRGBtoHSV(LPCHSLine_Color lpcolor);
void ConvertHSVtoRGB(LPCHSLine_Color lpcolor);
double max3(double num1,double num2,double num3);
double min3(double num1,double num2,double num3);
public: //パブリック関数
//コンストラクタ
CHSLine(void);
CHSLine(HDC hdc);
//デバイスコンテキスト設定
HDC SetDC(HDC hdc);
//現在選択されているデバイスコンテキストを取得
HDC GetDC(void);
//位置設定
void SetPosition(int x,int y);
void SetPositionX(int x);
void SetPositionY(int y);
void SetPosition(POINT pos);
//現在の位置取得
POINT GetPosition(void);
int GetPositionX(void);
int GetPositionY(void);
//描画(座標指定系)
void Draw(int end_x , int end_y , BOOL SetPosFromEndPos = TRUE);
void Draw(POINT end_pos , BOOL SetPosFromEndPos = TRUE);
void DrawEx(int start_x ,int start_y,int end_x , int end_y , BOOL SetPosFromEndPos = TRUE);
void DrawEx(POINT start,POINT end_pos,BOOL SetPosFromEndPos = TRUE);
BOOL DrawMultiPoint(LPPOINT lppoints,int num,BOOL SetPosFromEndPos = TRUE);
BOOL DrawMultiPointEx(LPPOINT lppoints,int num,BOOL StartOfCurrentPos = TRUE,BOOL SetPosFromEndPos = TRUE);
//描画(サイズ指定系)
BOOL DrawSize(int size_x , int size_y , BOOL SetPosFromEndPos = TRUE);
BOOL DrawSize(SIZE size , BOOL SetPosFromEndPos = TRUE);
BOOL DrawExSize(int start_x,int start_y,int size_x,int size_y,BOOL SetPosFromEndPos = TRUE);
BOOL DrawExSize(POINT start,SIZE size ,BOOL SetPosFromEndPos = TRUE);
//色設定
void SetColor(int r , int g , int b);
void SetColor(COLORREF rgb);
void SetColorR(int r);
void SetColorG(int g);
void SetColorB(int b);
void SetColorH(double h);
void SetColorS(double s);
void SetColorV(double v);
void SetColorHSV(double h , double s , double v);
//色設定取得
COLORREF GetColor(void);
void GetColor(int *pr , int *pg ,int *pb);
void GetColorHSV(double *ph , double *ps , double *pv);
int GetColorR(void);
int GetColorG(void);
int GetColorB(void);
double GetColorH(void);
double GetColorS(void);
double GetColorV(void);
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment