On the confusion of rgb numerical comparison - c++

I wrote a program that gives any RGB value and can find similar colors from the program.
But the result is a little confusing.
The program is a little long, mainly to fill in some RGB data.
The main key points are as follows
//MyColor.h
#pragma once
#ifndef __MYCOLOR_H__
#define __MYCOLOR_H__
#include <windef.h>
#include <wingdi.h>
#include <vector>
namespace my
{
struct ColorData
{
UINT8 family;
UINT16 id;
const char * name;
const char * hex;
UINT8 rgb[3];
ColorData(UINT8 _family, UINT16 _id, const char *_name, UINT8 _r, UINT8 _g, UINT8 _b, const char * _hex)
{
family = _family;
id = _id;
name = _name;
hex = _hex;
rgb[0] = _r;
rgb[1] = _g;
rgb[2] = _b;
}
ColorData(){};
};
/*
MyColorSpace::myColorFamily cc;
MyColorSpace::myColorFamily::data *da;
da = cc.Get(cc.family_blue, cc.blue_deepsky);
da = cc.Get(cc.family_green, cc.green_yellowGreen);
da = cc.Get(cc.family_orange, cc.orange_tomato);
debug(("name,hex,rgb:<%s>,<%s>,[%d,%d,%d]\n",da->name,da->hex,(da->rgb)[0],(da->rgb)[1],(da->rgb)[2]));
*/
class ColorFamily {
public:
enum family
{
family_gray = 0,
family_red = 1,
family_orange = 2,
family_brown = 3,
family_blue = 4,
family_green = 5,
family_pink = 6,
family_purple = 7,
family_white = 8,
family_yellow = 9
};
enum gray {
gray_gainsboro = 0,
gray_light = 1,
gray_silver = 2,
gray_dark = 3,
gray_ = 4,
gray_dim = 5,
gray_lightslate = 6,
gray_slate = 7,
gray_darkslate = 8,
gray_black = 9
};
enum red {
red_indian = 0,
red_lightcoral = 1,
red_salmon = 2,
red_darksalmon = 3,
red_lightsalmon = 4,
red_crimson = 5,
red_ = 6,
red_firebrick = 7,
red_dark = 8
};
enum orange {
orange_lightsalmon = 0,
orange_coral = 1,
orange_tomato = 2,
orange_red = 3,
orange_dark = 4,
orange_ = 5
};
enum brown {
brown_cornsilk = 0,
brown_blanchedalmond = 1,
brown_bisque = 2,
brown_navajowhite = 3,
brown_wheat = 4,
brown_burlywood = 5,
brown_tan = 6,
brown_rosy = 7,
brown_sandy = 8,
brown_goldenrod = 9,
brown_darkgoldenrod = 10,
brown_peru = 11,
brown_chocolate = 12,
brown_saddle = 13,
brown_sienna = 14,
brown_ = 15,
brown_maroon = 16
};
enum blue {
blue_aqua = 0,
blue_cyan = 1,
blue_lightcyan = 2,
blue_paleturquoise = 3,
blue_aquamarine = 4,
blue_turquoise = 5,
blue_mediumturquoise = 6,
blue_darkturquoise = 7,
blue_cadet = 8,
blue_steel = 9,
blue_lightsteel = 10,
blue_powder = 11,
blue_light = 12,
blue_sky = 13,
blue_lightsky = 14,
blue_deepsky = 15,
blue_dodger = 16,
blue_cornflower = 17,
blue_mediumslate = 18,
blue_royal = 19,
blue_ = 20,
blue_medium = 21,
blue_dark = 22,
blue_navy = 23,
blue_midnight = 24
};
enum green {
green_yellow = 0,
green_chartreuse = 1,
green_lawn = 2,
green_lime = 3,
green_limeGreen = 4,
green_pale = 5,
green_light = 6,
green_mediumspring = 7,
green_spring = 8,
green_mediumsea = 9,
green_sea = 10,
green_forest = 11,
green_ = 12,
green_dark = 13,
green_yellowGreen = 14,
green_olivedrab = 15,
green_olive = 16,
green_darkolive = 17,
green_mediumaquamarine = 18,
green_darksea = 19,
green_lightsea = 20,
green_darkcyan = 21,
green_teal = 22
};
enum pink {
pink_ = 0,
pink_light = 1,
pink_hot = 2,
pink_deep = 3,
pink_mediumvioletred = 4,
pink_palevioletred = 5
};
enum purple {
purple_lavender = 0,
purple_thistle = 1,
purple_plum = 2,
purple_violet = 3,
purple_orchid = 4,
purple_fuchsia = 5,
purple_magenta = 6,
purple_mediumorchid = 7,
purple_medium = 8,
purple_rebecca = 9,
purple_blueviolet = 10,
purple_darkviolet = 11,
purple_darkorchid = 12,
purple_darkmagenta = 13,
purple_ = 14,
purple_indigo = 15,
purple_slateblue = 16,
purple_darkslateblue = 17,
purple_mediumslateblue = 18
};
enum white {
white_ = 0,
white_snow = 1,
white_honeydew = 2,
white_mintcream = 3,
white_azure = 4,
white_aliceblue = 5,
white_ghost = 6,
white_smoke = 7,
white_seashell = 8,
white_beige = 9,
white_oldlace = 10,
white_floral = 11,
white_ivory = 12,
white_antique = 13,
white_linen = 14,
white_lavenderblush = 15,
white_mistyrose = 16
};
enum yellow {
yellow_gold = 0,
yellow_ = 1,
yellow_light = 2,
yellow_lemonchiffon = 3,
yellow_lightgoldenrod = 4,
yellow_papayawhip = 5,
yellow_moccasin = 6,
yellow_peachpuff = 7,
yellow_palegoldenrod = 8,
yellow_khaki = 9,
yellow_darkkhaki = 10
};
ColorFamily();
~ColorFamily() = default;
private:
ColorData * _detail;
public:
std::vector<ColorData>List;
ColorData* Get(const char * name);
ColorData* Get(UINT8 _family, UINT16 _id);
bool Get(UINT8 _r,UINT8 _g,UINT8 _b,ColorData &_out);
void FillColorData(ColorData &tar,ColorData* src);
};
}
#endif
//MyColor.cpp
#include "MyColor.h"
#include "stdlib.h"
#include "debug.h"
#define Less10(a,b) abs(a-b) < 10 ? true : false
namespace my
{
ColorFamily::ColorFamily()
{
//data da("",20,30,40,"#hex")
//List.push_back(data(0,"name", 20, 30, 40, "#hex"));
//gray
//gray
List.push_back(ColorData(0, 0, "gray_gainsboro", 220, 220, 220, "#dcdcdc"));
List.push_back(ColorData(0, 1, "gray_light", 211, 211, 211, "#d3d3d3"));
List.push_back(ColorData(0, 2, "gray_silver", 192, 192, 192, "#c0c0c0"));
List.push_back(ColorData(0, 3, "gray_dark", 169, 169, 169, "#a9a9a9"));
List.push_back(ColorData(0, 4, "gray_", 128, 128, 128, "#808080"));
List.push_back(ColorData(0, 5, "gray_dim", 105, 105, 105, "#696969"));
List.push_back(ColorData(0, 6, "gray_lightslate", 119, 136, 153, "#778899"));
List.push_back(ColorData(0, 7, "gray_slate", 112, 128, 144, "#708090"));
List.push_back(ColorData(0, 8, "gray_darkslate", 47, 79, 79, "#2f4f4f"));
List.push_back(ColorData(0, 9, "gray_black", 0, 0, 0, "#000000"));
//red
List.push_back(ColorData(1, 0, "red_indian", 205, 92, 92, "#cd5c5c"));
List.push_back(ColorData(1, 1, "red_lightcoral", 240, 128, 128, "#f08080"));
List.push_back(ColorData(1, 2, "red_salmon", 250, 128, 114, "#fa8072"));
List.push_back(ColorData(1, 3, "red_darksalmon", 233, 150, 122, "#e9967a"));
List.push_back(ColorData(1, 4, "red_lightsalmon", 255, 160, 122, "#ffa07a"));
List.push_back(ColorData(1, 5, "red_crimson", 220, 20, 60, "#dc143c"));
List.push_back(ColorData(1, 6, "red_", 255, 0, 0, "#ff0000"));
List.push_back(ColorData(1, 7, "red_firebrick", 178, 34, 34, "#b22222"));
List.push_back(ColorData(1, 8, "red_dark", 139, 0, 0, "#8b0000"));
//orange
List.push_back(ColorData(2, 0, "orange_lightsalmon", 255, 160, 122, "#ffa07a"));
List.push_back(ColorData(2, 1, "orange_coral", 255, 127, 80, "#ff7f50"));
List.push_back(ColorData(2, 2, "orange_tomato", 255, 99, 71, "#ff6347"));
List.push_back(ColorData(2, 3, "orange_red", 255, 69, 0, "#ff4500"));
List.push_back(ColorData(2, 4, "orange_dark", 255, 140, 0, "#ff8c00"));
List.push_back(ColorData(2, 5, "orange_", 255, 165, 0, "#ffa500"));
//brown
List.push_back(ColorData(3, 0, "brown_cornsilk", 255, 248, 220, "#fff8dc"));
List.push_back(ColorData(3, 1, "brown_blanchedalmond", 255, 235, 205, "#ffebcd"));
List.push_back(ColorData(3, 2, "brown_bisque", 255, 228, 196, "#ffe4c4"));
List.push_back(ColorData(3, 3, "brown_navajowhite", 255, 222, 173, "#ffdead"));
List.push_back(ColorData(3, 4, "brown_wheat", 245, 222, 179, "#f5deb3"));
List.push_back(ColorData(3, 5, "brown_burlywood", 222, 184, 135, "#deb887"));
List.push_back(ColorData(3, 6, "brown_tan", 210, 180, 140, "#d2b48c"));
List.push_back(ColorData(3, 7, "brown_rosy", 188, 143, 143, "#bc8f8f"));
List.push_back(ColorData(3, 8, "brown_sandy", 244, 164, 96, "#f4a460"));
List.push_back(ColorData(3, 9, "brown_goldenrod", 218, 165, 32, "#daa520"));
List.push_back(ColorData(3, 10, "brown_darkgoldenrod", 184, 134, 11, "#b8860b"));
List.push_back(ColorData(3, 11, "brown_peru", 205, 133, 63, "#cd853f"));
List.push_back(ColorData(3, 12, "brown_chocolate", 210, 105, 30, "#d2691e"));
List.push_back(ColorData(3, 13, "brown_saddle", 139, 69, 19, "#8b4513"));
List.push_back(ColorData(3, 14, "brown_sienna", 160, 82, 45, "#a0522d"));
List.push_back(ColorData(3, 15, "brown_", 165, 42, 42, "#a52a2a"));
List.push_back(ColorData(3, 16, "brown_maroon", 128, 0, 0, "#800000"));
//blue
List.push_back(ColorData(4, 0, "blue_aqua", 0, 255, 255, "#00ffff"));
List.push_back(ColorData(4, 1, "blue_cyan", 0, 255, 255, "#00ffff"));
List.push_back(ColorData(4, 2, "blue_lightcyan", 224, 255, 255, "#e0ffff"));
List.push_back(ColorData(4, 3, "blue_paleturquoise", 175, 238, 238, "#afeeee"));
List.push_back(ColorData(4, 4, "blue_aquamarine", 127, 255, 212, "#7fffd4"));
List.push_back(ColorData(4, 5, "blue_turquoise", 64, 224, 208, "#40e0d0"));
List.push_back(ColorData(4, 6, "blue_mediumturquoise", 72, 209, 204, "#48d1cc"));
List.push_back(ColorData(4, 7, "blue_darkturquoise", 0, 206, 209, "#00ced1"));
List.push_back(ColorData(4, 8, "blue_cadet", 95, 158, 160, "#5f9ea0"));
List.push_back(ColorData(4, 9, "blue_steel", 70, 130, 180, "#4682b4"));
List.push_back(ColorData(4, 10, "blue_lightsteel", 176, 196, 222, "#b0c4de"));
List.push_back(ColorData(4, 11, "blue_powder", 176, 224, 230, "#b0e0e6"));
List.push_back(ColorData(4, 12, "blue_light", 173, 216, 230, "#add8e6"));
List.push_back(ColorData(4, 13, "blue_sky", 135, 206, 235, "#87ceeb"));
List.push_back(ColorData(4, 14, "blue_lightsky", 135, 206, 250, "#87cefa"));
List.push_back(ColorData(4, 15, "blue_deepsky", 0, 191, 255, "#00bfff"));
List.push_back(ColorData(4, 16, "blue_dodger", 30, 144, 255, "#1e90ff"));
List.push_back(ColorData(4, 17, "blue_cornflower", 100, 149, 237, "#6495ed"));
List.push_back(ColorData(4, 18, "blue_mediumslate", 123, 104, 238, "#7b68ee"));
List.push_back(ColorData(4, 19, "blue_royal", 65, 105, 225, "#4169e1"));
List.push_back(ColorData(4, 20, "blue_", 0, 0, 255, "#0000ff"));
List.push_back(ColorData(4, 21, "blue_medium", 0, 0, 205, "#0000cd"));
List.push_back(ColorData(4, 22, "blue_dark", 0, 0, 139, "#00008b"));
List.push_back(ColorData(4, 23, "blue_navy", 0, 0, 128, "#000080"));
List.push_back(ColorData(4, 24, "blue_midnight", 25, 25, 112, "#191970"));
//green
List.push_back(ColorData(5, 0, "green_yellow", 173, 255, 47, "#adff2f"));
List.push_back(ColorData(5, 1, "green_chartreuse", 127, 255, 0, "#7fff00"));
List.push_back(ColorData(5, 2, "green_lawn", 124, 252, 0, "#7cfc00"));
List.push_back(ColorData(5, 3, "green_lime", 0, 255, 0, "#00ff00"));
List.push_back(ColorData(5, 4, "green_lime", 50, 205, 50, "#32cd32"));
List.push_back(ColorData(5, 5, "green_pale", 152, 251, 152, "#98fb98"));
List.push_back(ColorData(5, 6, "green_light", 144, 238, 144, "#90ee90"));
List.push_back(ColorData(5, 7, "green_mediumspring", 0, 250, 154, "#00fa9a"));
List.push_back(ColorData(5, 8, "green_spring", 0, 255, 127, "#00ff7f"));
List.push_back(ColorData(5, 9, "green_mediumsea", 60, 179, 113, "#3cb371"));
List.push_back(ColorData(5, 10, "green_sea", 46, 139, 87, "#2e8b57"));
List.push_back(ColorData(5, 11, "green_forest", 34, 139, 34, "#228b22"));
List.push_back(ColorData(5, 12, "green_", 0, 128, 0, "#008000"));
List.push_back(ColorData(5, 13, "green_dark", 0, 100, 0, "#006400"));
List.push_back(ColorData(5, 14, "green_yellow", 154, 205, 50, "#9acd32"));
List.push_back(ColorData(5, 15, "green_olivedrab", 107, 142, 35, "#6b8e23"));
List.push_back(ColorData(5, 16, "green_olive", 128, 128, 0, "#808000"));
List.push_back(ColorData(5, 17, "green_darkolive", 85, 107, 47, "#556b2f"));
List.push_back(ColorData(5, 18, "green_mediumaquamarine", 102, 205, 170, "#66cdaa"));
List.push_back(ColorData(5, 19, "green_darksea", 143, 188, 139, "#8fbc8b"));
List.push_back(ColorData(5, 20, "green_lightsea", 32, 178, 170, "#20b2aa"));
List.push_back(ColorData(5, 21, "green_darkcyan", 0, 139, 139, "#008b8b"));
List.push_back(ColorData(5, 22, "green_teal", 0, 128, 128, "#008080"));
//pink
List.push_back(ColorData(6, 0, "pink_", 255, 192, 203, "#ffc0cb"));
List.push_back(ColorData(6, 1, "pink_light", 255, 182, 193, "#ffb6c1"));
List.push_back(ColorData(6, 2, "pink_hot", 255, 105, 180, "#ff69b4"));
List.push_back(ColorData(6, 3, "pink_deep", 255, 20, 147, "#ff1493"));
List.push_back(ColorData(6, 4, "pink_mediumvioletred", 199, 21, 133, "#c71585"));
List.push_back(ColorData(6, 5, "pink_palevioletred", 219, 112, 147, "#db7093"));
//purple
List.push_back(ColorData(7, 0, "purple_lavender", 230, 230, 250, "#e6e6fa"));
List.push_back(ColorData(7, 1, "purple_thistle", 216, 191, 216, "#d8bfd8"));
List.push_back(ColorData(7, 2, "purple_plum", 221, 160, 221, "#dda0dd"));
List.push_back(ColorData(7, 3, "purple_violet", 238, 130, 238, "#ee82ee"));
List.push_back(ColorData(7, 4, "purple_orchid", 218, 112, 214, "#da70d6"));
List.push_back(ColorData(7, 5, "purple_fuchsia", 255, 0, 255, "#ff00ff"));
List.push_back(ColorData(7, 6, "purple_magenta", 255, 0, 255, "#ff00ff"));
List.push_back(ColorData(7, 7, "purple_mediumorchid", 186, 85, 211, "#ba55d3"));
List.push_back(ColorData(7, 8, "purple_medium", 147, 112, 219, "#9370db"));
List.push_back(ColorData(7, 9, "purple_rebecca", 102, 51, 153, "#663399"));
List.push_back(ColorData(7, 10, "purple_blueviolet", 138, 43, 226, "#8a2be2"));
List.push_back(ColorData(7, 11, "purple_darkviolet", 148, 0, 211, "#9400d3"));
List.push_back(ColorData(7, 12, "purple_darkorchid", 153, 50, 204, "#9932cc"));
List.push_back(ColorData(7, 13, "purple_darkmagenta", 139, 0, 139, "#8b008b"));
List.push_back(ColorData(7, 14, "purple_", 128, 0, 128, "#800080"));
List.push_back(ColorData(7, 15, "purple_indigo", 75, 0, 130, "#4b0082"));
List.push_back(ColorData(7, 16, "purple_slateblue", 106, 90, 205, "#6a5acd"));
List.push_back(ColorData(7, 17, "purple_darkslateblue", 72, 61, 139, "#483d8b"));
List.push_back(ColorData(7, 18, "purple_mediumslateblue", 123, 104, 238, "#7b68ee"));
//white
List.push_back(ColorData(8, 0, "white_", 255, 255, 255, "#ffffff"));
List.push_back(ColorData(8, 1, "white_snow", 255, 250, 250, "#fffafa"));
List.push_back(ColorData(8, 2, "white_honeydew", 240, 255, 240, "#f0fff0"));
List.push_back(ColorData(8, 3, "white_mintcream", 245, 255, 250, "#f5fffa"));
List.push_back(ColorData(8, 4, "white_azure", 240, 255, 255, "#f0ffff"));
List.push_back(ColorData(8, 5, "white_aliceblue", 240, 248, 255, "#f0f8ff"));
List.push_back(ColorData(8, 6, "white_ghost", 248, 248, 255, "#f8f8ff"));
List.push_back(ColorData(8, 7, "white_smoke", 245, 245, 245, "#f5f5f5"));
List.push_back(ColorData(8, 8, "white_seashell", 255, 245, 238, "#fff5ee"));
List.push_back(ColorData(8, 9, "white_beige", 245, 245, 220, "#f5f5dc"));
List.push_back(ColorData(8, 10, "white_oldlace", 253, 245, 230, "#fdf5e6"));
List.push_back(ColorData(8, 11, "white_floral", 255, 250, 240, "#fffaf0"));
List.push_back(ColorData(8, 12, "white_ivory", 255, 255, 240, "#fffff0"));
List.push_back(ColorData(8, 13, "white_antique", 250, 235, 215, "#faebd7"));
List.push_back(ColorData(8, 14, "white_linen", 250, 240, 230, "#faf0e6"));
List.push_back(ColorData(8, 15, "white_lavenderblush", 255, 240, 245, "#fff0f5"));
List.push_back(ColorData(8, 16, "white_mistyrose", 255, 228, 225, "#ffe4e1"));
//yellow
List.push_back(ColorData(9, 0, "yellow_gold", 255, 215, 0, "#ffd700"));
List.push_back(ColorData(9, 1, "yellow_", 255, 255, 0, "#ffff00"));
List.push_back(ColorData(9, 2, "yellow_light", 255, 255, 224, "#ffffe0"));
List.push_back(ColorData(9, 3, "yellow_lemonchiffon", 255, 250, 205, "#fffacd"));
List.push_back(ColorData(9, 4, "yellow_lightgoldenrod", 250, 250, 210, "#fafad2"));
List.push_back(ColorData(9, 5, "yellow_papayawhip", 255, 239, 213, "#ffefd5"));
List.push_back(ColorData(9, 6, "yellow_moccasin", 255, 228, 181, "#ffe4b5"));
List.push_back(ColorData(9, 7, "yellow_peachpuff", 255, 218, 185, "#ffdab9"));
List.push_back(ColorData(9, 8, "yellow_palegoldenrod", 238, 232, 170, "#eee8aa"));
List.push_back(ColorData(9, 9, "yellow_khaki", 240, 230, 140, "#f0e68c"));
List.push_back(ColorData(9, 10, "yellow_darkkhaki", 189, 183, 107, "#bdb76b"));
};
void ColorFamily::FillColorData(ColorData &tar,ColorData* src)
{
tar.family = src->family;
tar.hex = src->hex;
tar.id = src->id;
tar.name = src->name;
tar.rgb[0] = src->rgb[0];
tar.rgb[1] = src->rgb[1];
tar.rgb[2] = src->rgb[2];
}
ColorData* ColorFamily::Get(const char * name)
{
for (int i = 0; i < List.size(); i++)
{
ColorData da = List[i];
if (strcmp(da.name, name))
{
_detail->family = da.family;
_detail->hex = da.hex;
_detail->id = da.id;
_detail->name = da.name;
_detail->rgb[0] = da.rgb[0];
_detail->rgb[1] = da.rgb[1];
_detail->rgb[2] = da.rgb[2];
return _detail;
}
}
}
ColorData* ColorFamily::Get(UINT8 _family, UINT16 _id)
{
for (int i = 0; i < List.size(); i++)
{
_detail = &List[i];
if (_detail->family == _family && _detail->id == _id)
{
return _detail;
}
}
}
bool ColorFamily::Get(UINT8 _r,UINT8 _g,UINT8 _b,ColorData &_out)
{
debug("rgb(%d,%d,%d)\n", _r,_g,_b);
struct similar
{
UINT8 dt;
UINT8 family;
UINT8 color;
similar(UINT8 _dt, UINT8 _family, UINT8 _color){
dt = _dt;
family = _family;
color = _color;
}
};
std::vector<similar> sList;
for (int i = 0; i < List.size(); i++)
{
_detail = &List[i];
if (_detail->rgb[0] == _r && _detail->rgb[1] == _g && _detail->rgb[2] == _b)
{
FillColorData(_out,_detail);
return true;
}
}
for (int i = 0; i < List.size(); i++)
{
_detail = &List[i];
unsigned short sum = 0;
if (Less10(_detail->rgb[0],_r) &&
Less10(_detail->rgb[1],_g) &&
Less10(_detail->rgb[2],_b))
{
sum += abs(_detail->rgb[0] - _r);
sum += abs(_detail->rgb[1] - _g);
sum += abs(_detail->rgb[2] - _b);
debug("dc:%d,list(%d,%d,%d)\n",sum, _detail->rgb[0],_detail->rgb[1],_detail->rgb[2]);
sList.push_back(similar(sum,_detail->family,_detail->id));
}
}
unsigned short dt_min_idx = 0;
if(sList.size() > 0)
{
for (int i = 0; i < sList.size(); i++)
{
if(sList[dt_min_idx].dt >= sList[i].dt)
{
dt_min_idx = i;
}
}
UINT8 fid = sList[dt_min_idx].family;
UINT8 cid = sList[dt_min_idx].color;
FillColorData(_out,Get(fid,cid));
return true;
}
return false;
}
}
//main.cpp
#include <iostream>
#include <windows.h>
#include "MyColor.h"
#include "debug.h"
using namespace std;
my::bug d;
my::ColorFamily col;
int main()
{
my::ColorData cd;
UINT8 rgb[3] = {62,138,120};
bool rst = col.Get(rgb[0],rgb[1],rgb[2],cd);
if(rst)
debug("rst:%d \n rgb(%d,%d,%d)=>rgb(%d,%d,%d) \nfamily:%d,color:%d,name:%s\n",rst,rgb[0],rgb[1],rgb[2],cd.rgb[0],cd.rgb[1],cd.rgb[2],cd.family,cd.id, cd.name);
else
debug("no result\n");
system("pause");
return 0;
}
//ctrl + shift + p
and the result is:
rgb(62,138,120)
dc:176,list(64,224,208)
dc:76,list(70,130,180)
dc:141,list(65,105,225)
dc:50,list(60,179,113)
rst:1
The result of the program is roughly in line with my expectations, but there is something very confusing about it.
Here, for example, I clearly specify that three conditions are required to be true at the same time before I add it to the list.
if (Less10(_detail->rgb[0],_r) &&
Less10(_detail->rgb[1],_g) &&
Less10(_detail->rgb[2],_b))
{
...
}
But judging from the output, it seems that the program only compares the first condition.
debug init done
rgb(62,138,120)
dc:176,list(64,224,208)
dc:76,list(70,130,180)
dc:141,list(65,105,225)
dc:50,list(60,179,113)
################################################
rst:1
rgb(62,138,120)=>rgb(60,179,113)
family:5,color:9,name:green_mediumsea

Your use of macros is causing confusion.
You defined Less10 as follows:
#define Less10(a,b) abs(a-b) < 10 ? true : false
So let us expand your condition:
abs(_detail->rgb[0]-_r) < 10 ? true : false &&
abs(_detail->rgb[1]-_g) < 10 ? true : false &&
abs(_detail->rgb[2]-_b) < 10 ? true : false)
Since : has a very low operator precedence, it is parsed as follows:
abs(_detail->rgb[0]-_r) < 10 ? true :
(false && abs(_detail->rgb[1]-_g) < 10 ? true :
(false && abs(_detail->rgb[2]-_b) < 10 ? true : false)))
and since false && EXPR === false, it boils down to:
abs(_detail->rgb[0]-_r) < 10 ? true : false
To fix it, either make Less10 a real function, or wrap the macro definition in parens, and get rid of the extraneous ? true : false while you're at it (since the condition is already true or false)
#define Less10(a,b) (abs(a-b) < 10)

Related

How to generate complimentary SPWM using ATmega328 in Arduino IDE

Here generated complimentary PWM using ATmega328 in Arduino IDE.
The given code works well. It is generating complimentary PWM output but the problem is that one output is as desired, but the complimentary output is not as desired. Initially complimentary pin should be on HIGH and after SPWM cycles from lookUp table it should be HIGH forever till next pulse, never go for LOW. The other output is as desired, it is initially LOW and after SPWM pulses from lookUp it remains LOW till next pulses. I need to generate pulses as I attached. Also want to add deadtime.
#define MAX_COUNT 500 // (16 MHz / SW_FREQ) / 2
#define NO_OF_PULSES 160 // 16 kHz / 50 Hz = 320; 320 / 2 = 160 pulses in one half-cycle
int lookUp[NO_OF_PULSES] = {500, 490, 480, 471, 461, 451, 441, 431, 422, 412,
402, 393, 383, 374, 364, 355, 345, 336, 327, 318, 309, 300, 291,
282, 273, 264, 256, 247, 239, 230, 222, 214, 206, 198, 190, 183,
175, 168, 161, 153, 146, 140, 133, 126, 120, 113, 107, 101, 95,
90, 84, 79, 74, 69, 64, 59, 54, 50, 46, 42, 38, 34, 31, 28, 24,
22, 19, 16, 14, 12, 10, 8, 6, 5, 3, 2, 2, 1, 0, 0, 0, 0, 0, 1,
2, 2, 3, 5, 6, 8, 10, 12, 14, 16, 19, 22, 24, 28, 31, 34, 38,
42, 46, 50, 54, 59, 64, 69, 74, 79, 84, 90, 95, 101, 107, 113,
120, 126, 133, 140, 146, 153, 161, 168, 175, 183, 190, 198, 206,
214, 222, 230, 239, 247, 256, 264, 273, 282, 291, 300, 309, 318,
327, 336, 345, 355, 364, 374, 383, 393, 402, 412, 422, 431, 441,
451, 461, 471, 480, 490
};
volatile bool positiveHalf = true;
volatile bool zeroCrossing = false;
void setup() {
pinMode(9 , OUTPUT); // Pin 09 for PWM signal A
pinMode(10, OUTPUT); // Pin 10 for PWM signal B
TCCR1A = 0;
TCCR1B = 0;
TCCR1A = 0b11100000; // Set timer 1 to phase and frequency correct PWM mode (mode 8)
TCCR1B = 0b00010001; // Set no prescaler
ICR1 = MAX_COUNT; // Period for 16MHz crystal, for a switching frequency of 16 kHz for 320 subdevisions per 50 Hz sin wave cycle.
OCR1A = lookUp[0]; // Set top value for timer 1
OCR1B = lookUp[0];
TIMSK1 |= _BV(TOIE1); // Enable timer 1 overflow interrupt
sei();
}
ISR(TIMER1_OVF_vect) {
static int i = 1;
if (i >= NO_OF_PULSES) { // NO_OF_PULSES
i = 0;
}
OCR1A = lookUp[i];
OCR1B = lookUp[i];
if (i == 1) {
positiveHalf = !positiveHalf;
TCCR1A = positiveHalf ? 0b11100000 : 0b00000000; // +Ve half: Set OC1A (pin D9) on Compare Match; // Disconnect OC1B (pin D10); -Ve half: Opposite
}
i++;
}
void loop() {
}

Passing arguments to Base constructor using Derived class member variables in C/C++

I am building a class to control some hardware which has a few different versions. Because of this variety of versions, certain parameters need to be hardcoded, and they are different for each version. However, beyond those hardcoded parameters, all versions provide the same funcionality.
The way I thought I would architect this was to use a base class which contains all the methods needed, and derived classes (DerivedV1, DerivedV2, etc) where I would just define these hardcoded parameters as member variables and then pass them as constructions parameters to the base class.
Here is a minimal example of the code:
(this is deployed on a microcontroller hence the use of arrays instead of vectors, also disregard the use of std::cout, it was only included here to illustrate the problem)
#include <iostream>
using namespace std;
void print_array(uint16_t *array, uint16_t size){
cout<<"[ ";
for(int i=0; i < size-1; i++){
cout<<array[i]<<", ";
}
cout<<array[size-1]<<" ]"<<endl;
}
class BaseClass{
protected:
std::string id_;
uint16_t num_cats_;
uint16_t num_dogs_;
uint16_t *cat_mapping_;
uint16_t *dog_mapping_;
uint16_t combinations_;
public:
BaseClass(string id, uint16_t num_cats, uint16_t num_dogs,
uint16_t *cat_map, uint16_t *dog_map){
cout<<"Base Constructor"<<endl;
id_ = id;
num_cats_ = num_cats;
num_dogs_ = num_dogs;
cat_mapping_ = cat_map;
dog_mapping_ = dog_map;
combinations_ = num_cats_*num_dogs_;
cout<<"Num cats: "<<num_cats_<<endl;
cout<<"Num dogs: "<<num_cats_<<endl;
print_array(cat_mapping_, num_cats_);
print_array(dog_mapping_, num_dogs_);
cout<<"Combinations: "<<combinations_<<endl;
}
virtual ~BaseClass(){};
};
class DerivedClassV1 : public BaseClass
{
private:
uint16_t num_cats_ = 10;
uint16_t cat_map_[10] = {31, 15, 20, 32, 13, 25, 19, 16, 28, 23};
uint16_t num_dogs_ = 8;
uint16_t dog_map_[8] = {5, 25, 23, 4, 13, 15, 14, 26};
public:
DerivedClassV1(string id) : BaseClass(id, num_cats_, num_dogs_, cat_map_, dog_map_){
cout<<"Derived Constructor";
}
};
int main()
{
DerivedClassV1 dummy("v1");
return 0;
}
Execution of this code results in garbage being output:
Base Constructor
Num cats: 64
Num dogs: 64
[ 0, 0, 2, 0, 0, 0, 4781, 64, 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, 4704,
64, 0, 0, 3040, 64, 0, 0, 42640, 13254, 32766, 0, 0, 0, 0, 0, 0, 0, 0,
0, 44869, 10268, 32576, 0, 0, 0, 0 , 0, 42648, 13254, 32766, 0, 0, 0,
1, 0, 3456, 64, 0, 0, 0, 0, 0, 0, 13708, 48499 ]
[ 0, 0, 0, 0, 0, 0, 0, 4704, 64, 0, 0, 3040, 64, 0, 0, 42640, 13254,
32766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44869, 10268, 32576, 0, 0, 0, 0, 0,
42648, 13254, 32766, 0, 0, 0, 1, 0 , 3456, 64, 0, 0, 0, 0, 0, 0,
13708, 48499, 5513, 17381, 3040, 64, 0, 0, 42640, 13254, 32766, 0, 0,
0, 0, 0, 0, 0, 0, 0, 13708, 63219, 29188, 48153, 13708, 57481, 17840,
484 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4704, 64, 0, 0, 42648,
13254, 32766, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3040, 64, 0, 0,
42640, 13254, 32766, 0, 0, 0, 0, 0, 3081 ]
Combinations: 7936
Derived Constructor
What am I doing wrong here? Why are the arguments sent to the BaseClass not the correct ones defined in the derived class?
Should I be doing this differently? Any help is appreciated
The behaviour of your program is undefined.
Conceptually, DerivedClassV1::cat_map_ &c. do not exist at the point the base class is constructed.
A pointer to such an array (e.g. cat_map in the base class constructor) is effectively dangling.
Can't you use polymorphism to yield the appropriate arrays?
You can pass the DerivedClassV1 values to the BaseClass by using a template. But the values have to be static constants so they're initialized before the base class.
#include <iostream>
using namespace std;
void print_array(const uint16_t *array, uint16_t size){
cout<<"[ ";
for(int i=0; i < size-1; i++){
cout<<array[i]<<", ";
}
cout<<array[size-1]<<" ]"<<endl;
}
template <class T>
class BaseClass {
protected:
std::string id_;
const uint16_t *cat_mapping_ = T::cat_map_;
const uint16_t *dog_mapping_ = T::dog_map_;
uint16_t combinations_;
public:
BaseClass(string id){
cout<<"Base Constructor"<<endl;
id_ = id;
combinations_ = T::num_cats_*T::num_dogs_;
cout<<"Num cats: "<<T::num_cats_<<endl;
cout<<"Num dogs: "<<T::num_dogs_<<endl;
print_array(cat_mapping_, T::num_cats_);
print_array(dog_mapping_, T::num_dogs_);
cout<<"Combinations: "<<combinations_<<endl;
}
virtual ~BaseClass(){};
};
class DerivedClassV1 : public BaseClass<DerivedClassV1>
{
public:
static const uint16_t num_cats_ = 10;
static constexpr uint16_t cat_map_[10] = {31, 15, 20, 32, 13, 25, 19, 16, 28, 23};
static const uint16_t num_dogs_ = 8;
static constexpr uint16_t dog_map_[8] = {5, 25, 23, 4, 13, 15, 14, 26};
public:
DerivedClassV1(string id) : BaseClass(id){
cout<<"Derived Constructor";
}
};
constexpr uint16_t DerivedClassV1::cat_map_[10];
constexpr uint16_t DerivedClassV1::dog_map_[8];

How to split a value for showing on multiple 8-digit displays?

I am trying to write an Arduino sketch and I am getting a value from an external source which I am trying to display on three daisy-chained 8-digit led displays.
Currently I can display the individual digits like this:
//mydisplay.setDigit(displaynumber, position, value, comma);
mydisplay.setDigit(0, 7, 0, false);
mydisplay.setDigit(0, 6, 9, false);
mydisplay.setDigit(0, 5, 2, false);
mydisplay.setDigit(0, 4, 7, true);
mydisplay.setDigit(0, 3, 5, false);
mydisplay.setDigit(0, 2, 5, false);
mydisplay.setDigit(0, 1, 2, false);
mydisplay.setDigit(0, 0, 5, false);
mydisplay.setDigit(1, 7, 5, false);
mydisplay.setDigit(1, 6, 6, false);
mydisplay.setDigit(1, 3, 5, false);
mydisplay.setDigit(1, 2, 5, false);
mydisplay.setDigit(1, 1, 5, false);
mydisplay.setDigit(1, 0, 6, false);
mydisplay.setDigit(2, 7, 7, false);
mydisplay.setDigit(2, 6, 7, false);
mydisplay.setDigit(2, 5, 8, false);
mydisplay.setDigit(2, 4, 8, false);
mydisplay.setDigit(2, 3, 9, false);
mydisplay.setDigit(2, 2, 9, false);
mydisplay.setDigit(2, 1, 0, false);
mydisplay.setDigit(2, 0, 0, false);
This displays : 09275525 56 5556 77889900
but I don't know where to start if I just want to have a simple function where I can just input any variable and call a single function like this:
mydisplay.myfunctiontodisplay("09275525 56 5556 77889900");
I know I need to do a loop of some kind but i am not sure how to do it.
First, you map positions in a 24-character string, i.e. numbers from 0 to 23, inclusive, to (display, digit) pair. It appears from your example that the mapping should be as follows:
int pos = ... // This is the position inside your 24-character string
int dsp = pos / 8; // Display index
int dig = 7-pos%8; // Digit index
Now your setDigits function can be written as follows:
void setDigits(Display& display, const char* str) {
if (!str || strlen(str) != 24) {
return; // Accept only 24-character strings
}
for (int pos = 0 ; pos != 24 ; pos++) {
char c = str[pos];
int dsp = pos / 8;
int dig = 7-pos%8;
if (isdigit(c)) {
display.setDigit(dsp, dig, c-'0', false);
} else {
display.clear(dsp, dig);
}
}
}

How to create .swf file from multi .JPG images using swflib library in Visual C++?

I'm writing a c++ code to create a animate SWF file from multi JPG pictures.
Now, I have pictures like "image_0" to "image_100". I find a swflib library. I think it will help. So far, I can use this library's method to create .SWF file and the size of .SWF file is the sum of pictures in .JPG format.
So, I think I almost done. But ,SWF does not play. I am crazy.
Below this is the code which I modified:
`void CSWFLIBTestProjectDlg::CreateSWFMovie_Bitmap()
{
// Set movie params
SIZE_F movieSize = {100, 100};
int frameRate = 14;
POINT_F pt;
// Create empty .SWF file
CSWFMovie swfMovie;
swfMovie.OpenSWFFile(_T("SWF Sample Movies/Sample2.swf"), movieSize, frameRate);
SWF_RGB bgColor = {255, 255, 255};
swfMovie.SetBackgroundColor(bgColor);
// Define bitmap object
CSWFBitmap bitmap(2, (UCHAR*)"gif_0.jpg");//bm128
swfMovie.DefineObject(&bitmap, -1, true);
// Define custom shape
RECT_F shapeRect = {0, 0, 1000, 1000};
CSWFShape shape(1, shapeRect, 1);
SWF_RGBA lineColor = {0, 0, 0, 255};
shape.AddLineStyle(0, lineColor);
RECT_F bitmapRect = {0, 0, 1246, 622}; // size of the bitmap
RECT_F clipRect = {0, 0, 100, 100}; // where to fill
shape.AddBitmapFillStyle(bitmap.m_ID, SWF_FILLSTYLETYPE_BITMAP_0, bitmapRect, clipRect);
pt.x = 0;
pt.y = 0;
shape.ChangeStyle(1, 1, 0, &pt);
shape.AddLineSegment(100, 0);
shape.AddLineSegment(0, 100);
shape.AddLineSegment(-100, 0);
shape.AddLineSegment(0, -100);
swfMovie.DefineObject(&shape, shape.m_Depth, true);
swfMovie.ShowFrame();
/****************************************
* move
****************************************/
float i;
for (i=0; i<10; i++)
{
shape.Translate(i, 0);
swfMovie.UpdateObject(&shape, shape.m_Depth, NULL, -1);
swfMovie.ShowFrame();
//if (i>200)
//{
// swfMovie.RemoveObject(shape.m_Depth);
//}
}
/****************************************
* add jpg
****************************************/
swfMovie.RemoveObject(shape.m_Depth);
for (int i=1;i<=100;i++)
{
char filename[100];
sprintf(filename,"gif_%d%s",i,".jpg");
CSWFBitmap bitmap2(3, (UCHAR*)filename);//gif_0
swfMovie.DefineObject(&bitmap2, -1, true);//
// Define custom shape
RECT_F shapeRect2 = {0, 0, 1000, 1000};
CSWFShape shape2(1, shapeRect2, 1);
SWF_RGBA lineColor2 = {0, 0, 0, 255};
shape2.AddLineStyle(0, lineColor2);
RECT_F bitmapRect2 = {0, 0, 1246, 622}; // size of the bitmap
RECT_F clipRect2 = {0, 0, 100, 100}; // where to fill
shape2.AddBitmapFillStyle(bitmap2.m_ID, SWF_FILLSTYLETYPE_BITMAP_0, bitmapRect2, clipRect2);
pt.x = 0;
pt.y = 0;
shape2.ChangeStyle(1, 1, 0, &pt);
shape2.AddLineSegment(100, 0);
shape2.AddLineSegment(0, 100);
shape2.AddLineSegment(-100, 0);
shape2.AddLineSegment(0, -100);
swfMovie.UpdateObject(&shape2, shape2.m_Depth, NULL, -1);
//swfMovie.DefineObject(&shape2, shape2.m_Depth, true);
swfMovie.ShowFrame();
//swfMovie.RemoveObject(shape2.m_Depth);
}
// Close .SWF file
swfMovie.CloseSWFFile();
}`
can you tell me what's wrong with my code ? Thanks in advance.
I have found a way to create a .SWF file from a set of image using C++,and a swflib library.you can download it from the lib file website .in which there is a method named :CreateSWFMovie_Bitmap() here is the code i modified
void CSWFLIBTestProjectDlg::CreateSWFMovie_Bitmap()
{
SIZE_F movieSize = {4000, 4000};
int frameRate = 40;
POINT_F pt;
CSWFMovie swfMovie;
swfMovie.OpenSWFFile(_T("SWF Sample Movies/Sample2.swf"), movieSize, frameRate);
SWF_RGB bgColor = {255, 255, 255};
swfMovie.SetBackgroundColor(bgColor);
CSWFBitmap bitmap(2, (UCHAR*)"bm128.jpg");
swfMovie.DefineObject(&bitmap, -1, false);
RECT_F shapeRect = {0, 0, 1000, 1000};//shape大小
CSWFShape shape(1, shapeRect, 1);
SWF_RGBA lineColor = {0, 0, 0, 255};
shape.AddLineStyle(3, lineColor);
RECT_F bitmapRect = {0, 0, 128, 128}; // size of the bitmap
RECT_F clipRect = {0, 0, 100, 100}; // where to fill
shape.AddBitmapFillStyle(bitmap.m_ID, SWF_FILLSTYLETYPE_BITMAP_0, bitmapRect, clipRect);
pt.x = 0;
pt.y = 0;
shape.ChangeStyle(1, 1, 0, &pt);
shape.AddLineSegment(100, 0);
shape.AddLineSegment(0, 100);
shape.AddLineSegment(-100, 0);
shape.AddLineSegment(0, -100);
swfMovie.DefineObject(&shape, shape.m_Depth, true);
swfMovie.ShowFrame();
for (int i=0; i<100; i++)
{
char filename[50]="";
sprintf(filename,"gif_%d%s",i,".jpg");
CSWFBitmap bitmap2(300+i, (UCHAR*)filename);
swfMovie.DefineObject(&bitmap2, -1, false);//false
CSWFShape shape2(7+i,shapeRect,2+i);//depth值也不能一样 id不能重复
shape2.AddLineStyle(3, lineColor);
RECT_F bitmapRect2 = {0, 0, 128, 128};
RECT_F clipRect2 = {0, 0, 100, 100};
shape2.AddBitmapFillStyle(bitmap2.m_ID, SWF_FILLSTYLETYPE_BITMAP_0, bitmapRect2, clipRect2);
pt.x = 0;
pt.y = 0;
shape2.ChangeStyle(1, 1, 0, &pt);
shape2.AddLineSegment(1000, 0);
shape2.AddLineSegment(0, 1000);
shape2.AddLineSegment(-1000, 0);
shape2.AddLineSegment(0, -1000);
shape2.Translate(80, 0);
swfMovie.DefineObject(&shape2, shape2.m_Depth, true);//必须define才能动 可以不update
swfMovie.ShowFrame();
}
}

Declaring arrays similar to C style (C++)

In C a programmer can declare an array like so:
unsigned char Fonts[2][8] {
[1] = {0, 31, 0, 31, 0, 31, 0, 31}
};
And element [0] is likely random bits. Is there a similar way in C++?
This works in C++:
unsigned char foo [2][8] = {
{},
{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}
};
Here, foo[0] is zero-initialized as defined by the C++ standard (§8.5.5 - default initialization for POD types is zero-initialization). For non-POD-types the default constructor is called.
You can do this:
unsigned char Fonts[2][8] = {
{0},
{0, 31, 0, 31, 0, 31, 0, 31}
};
Why not just do
unsigned char Fonts[2][8] {
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 31, 0, 31, 0, 31, 0, 31}
};
?