Problem with GUI rotation

  1. What do you want to achieve?

I want to have a line that is centered at a point and follows the mouse by applying the correct size adjustment and rotation to reach the cursor.

  1. What is the issue?
    The actual length of the line is correct, but the rotation does not seem to be working. It either does not rotate at all in the correct place, is inverted, or does not go beyond a threshold. It seems to be stuck in only one quadrant at a time (the center assumed to be the origin) and does not pass correctly into the other three. I have found a way to get it to work for either the 1st or 4th, but not the other two.

First approach: (Works fine in the fourth quadrant, but not the others.)

Second approach: (Slight modification, now works in 1st, but not other 3.)

  1. What solutions have you tried so far?

As shown in the above two videos, I tried several modifications to the angle calculation logic, but none worked for all the angles. I also gave bing AI a go, but it also failed.

Here is my lua code if you are interested:

local m = game.Players.LocalPlayer:GetMouse()
local c = script.Parent.Center2
local l = c.Frame
local x1, x2, y1, y2, sqrt, abs, acos, deg = c.Position.X.Offset, 0, c.Position.Y.Offset, 0, math.sqrt, math.abs, math.acos, math.deg
while wait() do
	x2, y2 = m.X, m.Y+36
	l.Size = UDim2.new(0,sqrt(abs(x2-x1)^2+abs(y2-y1)^2),0,1)
    --where the actual angle calculation happens. This works for 4th quadrant, but 360- the angle works for first.
	c.Rotation = deg(acos(abs(x2-x1)/l.Size.X.Offset))
end

I would like to point out the following, c is a (0,1,0,1) GUI frame and is used as the anchor point so the GUI will rotate nicely. The actual line is parented to that, and so you change the center rotation, not the line’s. This is all in a standard screengui setup, I don’t think anything there is causing the problem, but rather the angle calculation code.
Thanks, let me know if you see anything that is the matter, and or how to fix it :slight_smile:

  1. Set anchor point to (0.5, 0.5) to center the line

  2. Calculate the displacement between the endpoints of the line

local from: Vector2 = --some random position
local to: Vector2 = UserInputService:GetMouseLocation()

local disp: Vector2 = to - from

  1. Use math.atan2 to calculate the angle of the displacement
--the initial returned angle is in radians so we need to convert it to degrees
local angle: number = math.deg(math.atan2(disp.Y, disp.X))

  1. Calculate the length of the line by simply applying the Pythagorean theorem to disp
local length: number = disp.Magnitude
  1. To finish, position the line right in the middle between to and from, set its size to the length, and set its rotation to the calculated angle
local middle: Vector2 = from:Lerp(to, .5)

local line: Frame = Instance.new('Frame')
line.AnchorPoint = Vector2.new(.5, .5)
line.Position = UDim2.fromOffset(middle.X, middle.Y)
line.Size = UDim2.fromOffset(length, 2) --4 is the thickness
line.Rotation = angle

I made many mistakes writing this the first time so here’s a demo

definitely not used for ESP tracers.rbxl (44.2 KB)

local line = script.Parent

local uis = game:GetService('UserInputService')
local rus = game:GetService('RunService')

local from: Vector2 = Vector2.new(100, 100)
uis.InputBegan:Connect(function(k, gp)
	if gp then return end
	if k.UserInputType == Enum.UserInputType.MouseButton1 then
		from = uis:GetMouseLocation()
	end
end)

rus.RenderStepped:Connect(function()
	local to: Vector2 = uis:GetMouseLocation()
	local disp: Vector2 = to - from
	local length: number = disp.Magnitude
	local angle: number = math.deg(math.atan2(disp.Y, disp.X))
	local center: Vector2 = from:Lerp(to, .5)
	
	line.Position = UDim2.fromOffset(center.X, center.Y)
	line.Size = UDim2.fromOffset(length, 2)
	line.Rotation = angle
end)
1 Like

Thanks, will try it out. It’s for a game that I might make that involves GUI wires, needing to place the initial point and then have the second point be with the mouse. Three lingering questions. 1. How is atan2 different from atan? 2. Why was my approach not working, was there a flaw in my math, or was it a flaw in my programming / GUI function misconception? Lastly, how are you using Magnitude, I thought that it was only for vector3s and the voxels.

Sorry for the late response.

You can look that up on Wikipedia, it explains better than I can. But to simplify, it automatically offsets the angle returned by the original atan function so that it is in the correct quadrant. If x is positive, then atan2(y, x) is the same as atan(y/x). But if x was negative, it needs to be flipped.
image

I’m gonna guess that this is the culprit:
image
Since the values can definitely be negative (it is on a cartesian coordinate plane), and yet you’re forcibly preventing that. Also, it was a bad decision to use arccosine instead of arctangent to start with for this specific purpose.

Magnitude is a property of all vectors. Roblox has Vector3 AND Vector2. I used magnitude for Vector2.

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.