Quickly Converting HSV to RGB?

Started by Scavenger, Wed 11/09/2013 23:38:19

Previous topic - Next topic

Scavenger

I'm trying to code a dynamic colour thing in AGS, so that I can change the colours of particular palette slots to emulate some neat effects. One of these is a shifting rainbow effect - going through hues smoothly and wrapping around. I would easily be able to do this kind of thing if I did it in HSV rather than RGB, as HSV has direct control over what a colour looks like, not it's light components.

Unfortunately, I'm at a bit of a loss figuring out how to do HSV to RGB at all. I'm looking at the formula to convert between the two colour systems, and I don't understand it. I've tried to convert the formula to AGSScript, but... it has syntax I'm not familiar with. Such as "C = V x SHSV". I'm not entirely sure what I'm doing.

Any suggestions for converting between colour formats?

Calin Leafshade

You might find these easier to convert.

theres no weird syntax here, just normal C.

Code: c

void RGBtoHSV( float r, float g, float b, float *h, float *s, float *v)
{
	float min, max, delta;
	min = MIN( r, g, b );
	max = MAX( r, g, b );
	*v = max;				// v
	delta = max - min;
	if( max != 0 )
		*s = delta / max;		// s
	else {
		// r = g = b = 0		// s = 0, v is undefined
		*s = 0;
		*h = -1;
		return;
	}
	if( r == max )
		*h = ( g - b ) / delta;		// between yellow & magenta
	else if( g == max )
		*h = 2 + ( b - r ) / delta;	// between cyan & yellow
	else
		*h = 4 + ( r - g ) / delta;	// between magenta & cyan
	*h *= 60;				// degrees
	if( *h < 0 )
		*h += 360;
}
void HSVtoRGB( float *r, float *g, float *b, float h, float s, float v )
{
	int i;
	float f, p, q, t;
	if( s == 0 ) {
		// achromatic (grey)
		*r = *g = *b = v;
		return;
	}
	h /= 60;			// sector 0 to 5
	i = floor( h );
	f = h - i;			// factorial part of h
	p = v * ( 1 - s );
	q = v * ( 1 - s * f );
	t = v * ( 1 - s * ( 1 - f ) );
	switch( i ) {
		case 0:
			*r = v;
			*g = t;
			*b = p;
			break;
		case 1:
			*r = q;
			*g = v;
			*b = p;
			break;
		case 2:
			*r = p;
			*g = v;
			*b = t;
			break;
		case 3:
			*r = p;
			*g = q;
			*b = v;
			break;
		case 4:
			*r = t;
			*g = p;
			*b = v;
			break;
		default:		// case 5:
			*r = v;
			*g = p;
			*b = q;
			break;
	}
}

Khris

Try this:
Code: ags
int GetColorFromHSV(int hue, float sat, float val) {
  float c = sat * val;
  float h1 = IntToFloat(hue)/60.0;
  float h2 = h1;
  while (h2 >= 2.0) h2 -= 2.0;
  float bet = h2 - 1.0;
  if (bet < 0.0) bet = -bet;
  float x = c * (1.0 - bet);
  float rr[6], gg[6], bb[6];
  rr[0] = c; rr[1] = x;                       rr[4] = x; rr[5] = c;
  gg[0] = x; gg[1] = c; gg[2] = c; gg[3] = x;
                        bb[2] = x; bb[3] = c; bb[4] = c; bb[5] = x;
  float r1 = rr[FloatToInt(h1)];
  float g1 = gg[FloatToInt(h1)];
  float b1 = bb[FloatToInt(h1)];
  float m = val - c;
  r1 = (r1 + m) * 256.0;
  g1 = (g1 + m) * 256.0;
  b1 = (b1 + m) * 256.0;
  //Display("%f, %f, %f", r1, g1, b1);
  int r = FloatToInt(r1, eRoundNearest) % 256;
  int g = FloatToInt(g1, eRoundNearest) % 256;
  int b = FloatToInt(b1, eRoundNearest) % 256;
  return Game.GetColorFromRGB(r, g, b);
}


Here's an example shot:
[imgzoom]http://i.imgur.com/VpA5eTz.png[/imgzoom]

Top is saturation 0.8, value ranging from 1.0 (top) to 0.0 (bottom)
Bottom is value = 0.9, saturation ranging from 1.0 (top) to 0.0 (bottom)

SMF spam blocked by CleanTalk