Help with GUI and Trigonometry

I’m attempting to make a custom joystick for mobile players. The joystick does work but I was wondering if I could make the JoyStick move around in a circle radius rather than a box.

I’d assumed that I would use trigonometry to combat this problem I just haven’t found a way yet and was wondering what you might think would work.

Current Code
	local radius = self.JoyStick.Parent.Size.X.Offset / 2 -- not the best way to do this but it works

	local pos = self.JoyStick.Position
        

	self.JoyStick.Position = UDim2.new(
		.5,
		math.clamp(pos.X.Offset, -(radius), radius),
		.5,
		math.clamp(pos.Y.Offset,-(radius), radius)
	) -- when the joystick is being dragged

If you need me to elaborate please tell me, and thanks a ton if you could help!

It returns the error:
invalid argument #3 to 'clamp' (max must be greater than or equal to min)

would i just switch the min and max around in the clamp?




local radius = self.JoyStick.Parent.AbsoluteSize.X / 2

local pos = self.JoyStick.Position

local X = math.clamp(pox.X.Offset,-radius,radius)
local range = math.sqrt((radius^2)-(X^2))
local Y = math.clamp(pos.Y.Offset,-range/2,range/2)
local position = Vector2.new(X,Y)

self.JoyStick.Position = UDim2.new(
	.5,
	position.X,
	.5,
	position.Y
) 

basically just finding a perpendicular bisector of a chord and using pythagoras. No trigonometry is necessary.
2 Likes
local radius = self.Joystick.Parent.Size.X.Offset / 2

local pos = Vector2.new(
    self.Joystick.Position.X.Offset,
    self.Joystick.Position.Y.Offset
)
if pos.Magnitude > radius then
    pos = pos.Unit * radius
end

self.Joystick.Position = UDim2.new(
    0.5,
    pos.X,
    0.5,
    pos.Y
)
1 Like

This resulted in:

invalid argument #3 to 'clamp' (max must be greater than or equal to min)

This resulted in the JoyStick not moving around at all sadly

Tysm @goldenstein64 , and thank you to @xendatro and @RatiusRat for contributing too means a ton!

1 Like

This solution works but there is a way to do it without if statements (which is more preferable).

local radius = --> radius of the controller
local pos = --> position of the joystick relative to the center of the controller
local mag = math.clamp(pos.Magnitude, 0, radius) --> length of the joystick, clamped to the size of the radius
local dir = pos.Unit --> direction of the joystick
Joystick.Position = UDim2.new(
    0.5,
    dir.X * mag,
    0.5,
    dir.Y * mag
)

This method can be thought of like this:

  1. The radius is the max distance away from the center of the controller
  2. The magnitude is the current distance away from the center of the controller, clamped to the radius
  3. The direction is a unit vector of the center of the controller to the current position
  4. The direction is multiplied by the magnitude, extending the length. The length will never exceed the radius because magnitude will always be <= radius
2 Likes