大概思路:采集摇杆AD值后得到直径为d的圆内的点在直角坐标系下的坐标x,y。需要调节亮度需要另外一路滑动电阻z。
直角坐标系x,y,z转极坐标系,极坐标系极径对应HSV颜色空间的S,极角对应HSV颜色空间H,直角坐标系z对应HSV颜色空间V。HSV转RGB得到RGB值。代码如下,输入x,y,z 取值范围[0, 100],得到R,G,B值取值范围[0, 255]。代码如下:
#include "stdio.h"
#include "stdint.h"
#include "stdlib.h"
#include "math.h"
void HSVtoRGB(uint8_t *r, uint8_t *g, uint8_t *b, uint16_t h, uint16_t s, uint16_t v)
{
// R,G,B from 0-255, H from 0-360, S,V from 0-100
int i;
float RGB_min, RGB_max;
RGB_max = v*2.55f;
RGB_min = RGB_max*(100 - s) / 100.0f;
i = h / 60;
int difs = h % 60; // factorial part of h
// RGB adjustment amount by hue
float RGB_Adj = (RGB_max - RGB_min)*difs / 60.0f;
switch (i) {
case 0:
*r = RGB_max;
*g = RGB_min + RGB_Adj;
*b = RGB_min;
break;
case 1:
*r = RGB_max - RGB_Adj;
*g = RGB_max;
*b = RGB_min;
break;
case 2:
*r = RGB_min;
*g = RGB_max;
*b = RGB_min + RGB_Adj;
break;
case 3:
*r = RGB_min;
*g = RGB_max - RGB_Adj;
*b = RGB_max;
break;
case 4:
*r = RGB_min + RGB_Adj;
*g = RGB_min;
*b = RGB_max;
break;
default: // case 5:
*r = RGB_max;
*g = RGB_min;
*b = RGB_max - RGB_Adj;
break;
}
}
//直角坐标系转极坐标系,极坐标系对应HSV,h=角度,s=长度,HSV转RGB
int main(int argc, char *argv[]){
uint8_t r=0, g=0, b=0;
uint8_t h = 0;
uint8_t s = 0;
uint8_t v = 0;
int8_t x=atoi(argv[1]), y=atoi(argv[2]), z=atoi(argv[3]); //x,y,z [0, 100]
s = sqrt(x*x + y*y);
if(s == 0){
h = 0;
}else{
h = (180/(4*atan(1))) * atan2(y, x);
}
v = z;
HSVtoRGB(&r, &g, &b, h, s, v);
printf("h=%d, s=%d, v=%d, r=%d, g=%d, b=%d\n", h, s, v, r, g, b);
return 0;
}