Color wheel returns a totally different color (HSV)

i’m trying to make a color wheel, which is going really well but for whatever reason the color that’s being returned is not at all equal to the color that’s actually being selected, why is this?


video:


code:

local function GetColorFromPosition(inputPosition: Vector2)
	-- get wheel center and radius
	local wheelCenter = colorWheel.AbsolutePosition + colorWheel.AbsoluteSize / 2
	local wheelRadius = colorWheel.AbsoluteSize.X / 2
	
	-- get offset
	local positionOffset = inputPosition - wheelCenter
	
	-- calculate distance
	local distanceFromCenter = positionOffset.Magnitude
	local normalizedDistance = math.clamp(distanceFromCenter / wheelRadius, 0, 1)
	
	-- calculate angle
	local angle = math.atan2(positionOffset.Y, -positionOffset.X)
	if angle < 0 then
		angle = angle + (math.pi * 2)
	end
	
	-- convert angle to hue
	local hue = angle / (math.pi * 2)
	
	-- convert hsv to color
	local color = Color3.fromHSV(hue, normalizedDistance, 1)
	return color
end

local function EditColor(input: InputObject)
	-- get input type and state
	local inputType = input.UserInputType
	local inputState = input.UserInputState
	
	print(isEditingColor)
	
	if not isEditingColor then return end
	
	-- controller support
	if input.UserInputType == Enum.UserInputType.Gamepad1 then
		if input.KeyCode == Enum.KeyCode.Thumbstick1 then
			UpdateCursorWithController(input.Position, 5)
		elseif input.KeyCode == Enum.KeyCode.DPadUp then
			UpdateCursorWithController(Vector2.new(0, -1), 10)
		elseif input.KeyCode == Enum.KeyCode.DPadDown then
			UpdateCursorWithController(Vector2.new(0, 1), 10)
		elseif input.KeyCode == Enum.KeyCode.DPadLeft then
			UpdateCursorWithController(Vector2.new(-1, 0), 10)
		elseif input.KeyCode == Enum.KeyCode.DPadRight then
			UpdateCursorWithController(Vector2.new(1, 0), 10)
		end
	end
	
	-- see if the player is trying to edit the color
	if inputType == Enum.UserInputType.MouseMovement or inputState == Enum.UserInputState.Change then
		local inputPosition = Vector2.new(input.Position.X, input.Position.Y)
		
		UpdateColorWheelCursorPosition(inputPosition)
		local color = GetColorFromPosition(inputPosition)
		colorResultFrame.BackgroundColor3 = color
	end
end

Can you please print out the value of angle, to see if it’s what you would expect?

ouch, the angle caps out at 6 and resets at 0

i don’t quite think it should be this way

I assume you mean 6.28, not 6? 6.28 is the equivalent of 2*pi.

How often does it reset to 0?

yes

when you do a full “spin” around the wheel
the reset is always consistent (at the same position) no matter where the first input is

Interesting, try replacing the hue variable with this one, this one makes sure 0 degrees(12 o’clock) is red.

local hue = (angle + math.pi / 2) / (math.pi * 2)

But im not sure if this might fix it.

That seems to be working correctly then. If you print out the hue value instead, does it stay between 0 and 1, and is it 0 at the top (and almost 1 slightly to the left of the top)?

this… almost! does it

but the color is flipped around, so if i go to yellow (right), it displays pink (which is on the left)

but if i go to cyan, it’s actually cyan

with my method, it does stay between 0 and 1, and the left top corner displays 0.8(insert number spam)

with @JAcoboiskaka1121 's method, the hue seems to cap out at 1.2, and top left displays 1 (or 1.1)

I would try negating the atan2 function. Maybe that might work??

local angle = -math.atan2(positionOffset.Y, -positionOffset.X)
if angle < 0 then
		angle = angle + (math.pi * 2)
	end

if you try modifying this to be:

angle += math.pi

does it have any effect?

(also, you may not need the minus before the x position in local angle = math.atan2(positionOffset.Y, -positionOffset.X))

nope, that just sets us back to square 1

hue caps out at 0.75 now :person_shrugging:

although THIS fixes the issue by 99%

every color works, but for whatever reason, yellow gets set to pink, so yellow in unachievable?

Can you please provide the current code (with all modifications)?

Alternatively, are you able to provide just the flair editor GUI as a .rbxm file?

Subtract 90 degrees from the angle.

nawhhh this doesn’t work

this code doesn’t include @awry_y 's suggestion

local function GetColorFromPosition(inputPosition: Vector2)
	-- get wheel center and radius
	local wheelCenter = colorWheel.AbsolutePosition + colorWheel.AbsoluteSize / 2
	local wheelRadius = colorWheel.AbsoluteSize.X / 2
	
	-- get offset
	local positionOffset = inputPosition - wheelCenter
	
	-- calculate distance
	local distanceFromCenter = positionOffset.Magnitude
	local normalizedDistance = math.clamp(distanceFromCenter / wheelRadius, 0, 1)
	
	-- calculate angle
	local angle = math.atan2(positionOffset.Y, positionOffset.X)
	if angle < 0 then
		angle = angle + (math.pi * 2)
	end
		
	-- convert angle to hue
	local hue = (angle + math.pi / 2) / (math.pi * 2)
	
	print(hue)
	
	-- convert hsv to color
	local color = Color3.fromHSV(hue, normalizedDistance, 1)
	return color
end

local function EditColor(input: InputObject)
	-- get input type and state
	local inputType = input.UserInputType
	local inputState = input.UserInputState
	
	print(isEditingColor)
	
	if not isEditingColor then return end
	
	-- controller support
	if input.UserInputType == Enum.UserInputType.Gamepad1 then
		if input.KeyCode == Enum.KeyCode.Thumbstick1 then
			UpdateCursorWithController(input.Position, 5)
		elseif input.KeyCode == Enum.KeyCode.DPadUp then
			UpdateCursorWithController(Vector2.new(0, -1), 10)
		elseif input.KeyCode == Enum.KeyCode.DPadDown then
			UpdateCursorWithController(Vector2.new(0, 1), 10)
		elseif input.KeyCode == Enum.KeyCode.DPadLeft then
			UpdateCursorWithController(Vector2.new(-1, 0), 10)
		elseif input.KeyCode == Enum.KeyCode.DPadRight then
			UpdateCursorWithController(Vector2.new(1, 0), 10)
		end
	end
	
	-- see if the player is trying to edit the color
	if inputType == Enum.UserInputType.MouseMovement or inputState == Enum.UserInputState.Change then
		local inputPosition = Vector2.new(input.Position.X, input.Position.Y)
		
		UpdateColorWheelCursorPosition(inputPosition)
		local color = GetColorFromPosition(inputPosition)
		colorResultFrame.BackgroundColor3 = color
	end
end

EDIT:

the reason why yellow isn’t achievable is because the hue caps out at 1.2 and starts at 0.2

it reaches 1.2 when your cursor reaches yellow, and 0.2 is located on pink

I guess try returning the hue variable to the normalised one from your original script:

local hue = angle / (math.pi * 2)

Im not sure what else I can think of if this doesn’t fix it.

I messed around and ended up with the following (working) code:

local colorWheel = script.Parent

local function GetColorFromPosition(inputPosition: Vector2)
	-- get wheel center and radius
	local wheelCenter = colorWheel.AbsolutePosition + colorWheel.AbsoluteSize / 2
	local wheelRadius = colorWheel.AbsoluteSize.X / 2

	-- get offset
	local positionOffset = (inputPosition - wheelCenter)
		
	-- calculate distance
	local distanceFromCenter = positionOffset.Magnitude
	local normalizedDistance = math.clamp(distanceFromCenter / wheelRadius, 0, 1)

	-- calculate angle
	local angle = math.atan(positionOffset.Y / positionOffset.X) + math.pi / 2
	if positionOffset.X <= 0 then angle += math.pi end
	
	print(math.deg(angle))

	-- convert angle to hue
	local hue = (angle) / (math.pi * 2)

	--print(hue)

	-- convert hsv to color
	local color = Color3.fromHSV(hue, normalizedDistance, 1)
	return color
end

local mouse = game.Players.LocalPlayer:GetMouse()

while true do
	task.wait()
	script.Parent.BackgroundColor3 = GetColorFromPosition(Vector2.new(mouse.X, mouse.Y))
end

The key part is to make the angle be calculated like this:

local angle = math.atan(positionOffset.Y / positionOffset.X) + math.pi / 2
if positionOffset.X <= 0 then angle += math.pi end

and don’t add anything to the hue.

2 Likes

Can you not cap hue? I also recommend that you print the angle. And also subtract or add math.pi/2 (if you literally subtracted 90 from it.)

1 Like

wowzies… my color wheel genius!
idk how you did this but i thank you for doing it

:sob: :sob:

i’m not that dumb yet

They just added 90 degrees into it because math.atan2() considers 0 degree to be the right side of the screen. Also by using anti-tan which you didn’t use properly.

1 Like