🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

How do I get the marker position on an hsv color wheel, from rgb 0-1 value

Started by
4 comments, last by SelethD 2 years, 1 month ago

I have a color wheel for my game, and I get an hsv value from it, then using ‘in engine’ api, I can get an rgb from the hsv values (the rgb ranges 0-1 for its color values)

However, I need to do the opposite. I need to start with an rgb, and convert that to an hsv, and I know the v is just a position on a slider, but how do I calculate where to put the color wheel marker based on the h, and s value.

here is the color wheel I am using.

I appreciate any help on this, thanks

Edit, I forgot to add, I am using lua, in the Roblox engine.

<code>

local function GetColor()

local wheelCenter = Vector2.new(

Wheel.AbsolutePosition.X + (Wheel.AbsoluteSize.X/2),

Wheel.AbsolutePosition.Y + (Wheel.AbsoluteSize.Y/2))

local markerCenter = Vector2.new(

WheelMarker.AbsolutePosition.X + (WheelMarker.AbsoluteSize.X/2),

WheelMarker.AbsolutePosition.Y + (WheelMarker.AbsoluteSize.Y/2))

local h = (math.pi - math.atan2(markerCenter.Y - wheelCenter.Y, markerCenter.X - wheelCenter.X)) / (math.pi * 2)

local s = (wheelCenter - markerCenter).Magnitude / (Wheel.AbsoluteSize.X/2)

Slider.UIGradient.Color = ColorSequence.new{

ColorSequenceKeypoint.new(0, Color3.fromHSV(math.clamp(h, 0, 1), math.clamp(s, 0, 1), 1)),

ColorSequenceKeypoint.new(1, Color3.new(0, 0, 0))

}

local color = Color3.fromHSV(math.clamp(h, 0, 1), math.clamp(s, 0, 1), math.clamp(Value, 0, 1))

Swatch.BackgroundColor3 = color

Result.Value = color

end

--=======================================================

function WheelMath(input)

local r = Wheel.AbsoluteSize.x/2

local d = Vector2.new(input.Position.x, input.Position.y) - Wheel.AbsolutePosition - Wheel.AbsoluteSize/2

if (d:Dot(d) > r*r) then

d = d.unit * r

end

WheelMarker.Position = UDim2.new(.5, d.x, .5, d.y)

GetColor()

end

</code>

Advertisement

This works for my color wheel, which has blue in the lower left and red to the right. Your wheel is mirrored compared to normal HSV, so you would need to negate the vector.

Vector2f polar( float angle )
{
	return Vector2f( math::cos( angle ), math::sin( angle ) );
}

Vector2f getHSVPoint( const Vector4f& rgb )
{
	// Convert linear RGB color to HSV
	float hsv[3];
	ColorSpace::convert_RGB_HSV( rgb, hsv );
	
	return center + hsv[1]*radius*Vector2f::polar( hsv[0]*2.0f*math::pi<float>() );
}

EDIT: nevermind, I overlooked an api call that can go from rgb to hsv, so now I can test your above code, thanks.

@Aressera Any help on getting the hsv from an rgb with range 0-1 (float)? I tried two examples online, but they are not returning the correct hsv values.

/// Convert the gamma from linear RGB to sRGB space.
template < typename T >
inline static T gamma_RGB_sRGB( T x )
{
	return (x <= T(0.0031306684425005883)) ? (x * T(12.92)) : (T(1.055)*math::pow( x, T(1)/T(2.4) ) - T(0.055));
}

/// Convert from the linear RGB color space to the sRGB color space.
template < typename T >
inline static void convert_RGB_sRGB( const T rgb[3], T srgb[3] )
{
	srgb[0] = gamma_RGB_sRGB(rgb[0]);
	srgb[1] = gamma_RGB_sRGB(rgb[1]);
	srgb[2] = gamma_RGB_sRGB(rgb[2]);
}

/// Convert from the sRGB color space to the HSV color space.
template < typename T >
inline static void convert_sRGB_HSV( const T srgb[3], T hsv[3] )
{
	const T rgbMax = math::max( srgb[0], math::max( srgb[1], srgb[2] ) );
	const T rgbMin = math::min( srgb[0], math::min( srgb[1], srgb[2] ) );
	T C = rgbMax - rgbMin;
	T V = rgbMax;
	T H, S;
	
	if ( C > T(0) )
	{
		if ( rgbMax == srgb[0] )
		{
			H = (srgb[1] - srgb[2]) / C;
			
			if ( srgb[1] < srgb[2] )
				H += 6;
		}
		else if ( rgbMax == srgb[1] )
			H = 2 + (srgb[2] - srgb[0]) / C;
		else
			H = 4 + (srgb[0] - srgb[1]) / C;
		
		H /= T(6);
		S = C / rgbMax;
	}
	else
		H = S = T(0);
	
	hsv[0] = H;
	hsv[1] = S;
	hsv[2] = V;
}

/// Convert from the linear RGB color space to the HSV color space.
template < typename T >
inline static void convert_RGB_HSV( const T rgb[3], T hsv[3] )
{
	T srgb[3];
	convert_RGB_sRGB( rgb, srgb );
	convert_sRGB_HSV( srgb, hsv );
}

@Aressera Thank you so much, I got it working.

This topic is closed to new replies.

Advertisement