Here is code for doing an RGB touch selection from a color wheel. It converts rectangular XY coords to polar coords for HSV and then to RGB.
Our setup has RGB and White LEDs (that we control separately). So just ignore the W.
Hopefully this saves someone time.
Cheers,
Mike Spenard
PP Systems
sender; /* the method is called from the sender object */
var float X;
var float Y;
var int16 H;
var int16 S;
var int16 V;
var float perR = 100.0;
var float perG = 100.0;
var float perB = 100.0;
var float perW = 100.0;
// normalize X,Y from touch
X = ((RGB_SimpleTouchHandler.CurrentPos.x - ColorWheel.Bounds.x1) ) - 100; // get X and range -100 to +100
Y = ((RGB_SimpleTouchHandler.CurrentPos.y - ColorWheel.Bounds.y1) ) - 100; // get Y and range -100 to +100
// Calculate radius ///////////////////////////
var float r = math_sqrt((X * X ) + ( Y * Y ));
// Calculate angle ////////////////////////////
var float angle = 0.0;
if ( r > 0.0 )
angle = math_acos( X / r );
else // were at center
{
R = 255;
G = 255;
B = 255;
perW = ((float)W / 255.0) * 100.0;
RGBWcontrolButton.Label = string(perR,0,0) + "-" + string(perG,0,0) + "-" + string(perB,0,0) + "-" + string(perW,0,0);
return;
}
if ( Y > 0.0 )
angle = 360.0 - angle;
// rotate everything 90deg counter-clockwise
angle = angle - 90.0;
if(angle < 0.0)
angle = 360.0 - angle;
// convert to HSV ////////////////////////////
// Hue = angle
H = (int16)angle;
// Saturation = radius
if(r > 100.0)
S = 100;
else
S = (int16)r;
// just peg V to 100
V = 100;
// convert HSV to RGB /////////////////////////
var int16 i;
var float RGB_max = (float)V*2.55;
var float RGB_min = RGB_max*(float)(100-S) / 100.0;
i = (int16)(H / 60);
var int16 difs = (int16)(H % 60); // factoral part of H
// RGB adjustment by hue
var float RGB_adj = (RGB_max - RGB_min)*(float)difs / 60.0;
switch(i)
{
case 0:
{
R = (uint8)RGB_max;
G = (uint8)(RGB_min + RGB_adj);
B = (uint8)RGB_min;
}
case 1:
{
R = (uint8)(RGB_max - RGB_adj);
G = (uint8)RGB_max;
B = (uint8)RGB_min;
}
case 2:
{
R = (uint8)RGB_min;
G = (uint8)RGB_max;
B = (uint8)(RGB_min + RGB_adj);
}
case 3:
{
R = (uint8)RGB_min;
G = (uint8)(RGB_max - RGB_adj);
B = (uint8)RGB_max;
}
case 4:
{
R = (uint8)(RGB_min + RGB_adj);
G = (uint8)RGB_min;
B = (uint8)RGB_max;
}
default:
{
R = (uint8)RGB_max;
G = (uint8)RGB_min;
B = (uint8)(RGB_max - RGB_adj);
}
}
ColorCircle.Color.red = R;
ColorCircle.Color.green = G;
ColorCircle.Color.blue = B;
// limit XY based on Radius
if(r > 100.0)
{
if (X > 0.0 && Y < 0.0)
{
X = 100.0*math_sin(angle);
Y = 100.0*math_cos(angle) * -1.0;
}
else
{
X = 100.0*math_sin(angle) * -1.0;
Y = 100.0*math_cos(angle) * -1.0;
}
}
// position cross-hair
var uint8 line_length = 10;
Xline.Point1.x = (int32)X - (line_length / 2) + (ColorWheel.Bounds.x1 + ColorWheel.Bounds.w / 2);
Xline.Point2.x = (int32)X + (line_length / 2) + (ColorWheel.Bounds.x1 + ColorWheel.Bounds.w / 2);
Xline.Point1.y = (int32)Y + (ColorWheel.Bounds.y1 + ColorWheel.Bounds.h / 2);
Xline.Point2.y = (int32)Y + (ColorWheel.Bounds.y1 + ColorWheel.Bounds.h / 2);
Yline.Point1.x = (int32)X + ColorWheel.Bounds.x1 + (ColorWheel.Bounds.w / 2);
Yline.Point2.x = (int32)X + ColorWheel.Bounds.x1 + (ColorWheel.Bounds.w / 2);
Yline.Point1.y = (int32)Y - (line_length / 2) + (ColorWheel.Bounds.y1 + ColorWheel.Bounds.h / 2);
Yline.Point2.y = (int32)Y + (line_length / 2) + (ColorWheel.Bounds.y1 + ColorWheel.Bounds.h / 2);
perR = ((float)R / 255.0) * 100.0;
perG = ((float)G / 255.0) * 100.0;
perB = ((float)B / 255.0) * 100.0;
perW = ((float)W / 255.0) * 100.0;
RGBWcontrolButton.Label = string(perR,0,0) + "-" + string(perG,0,0) + "-" + string(perB,0,0) + "-" + string(perW,0,0);
