Calculating line rotation

I’m making a system where you can connect two points to each other with a line, and have the basic mechanics down for modifying the line’s size and position. The thing that stumped me is calculating the rotation needed to make the line actually point towards the mouse’s current position. Here’s my current code:

local lineTemplate = script.Parent.Frame
local mouse = game.Players.LocalPlayer:GetMouse()

script.Parent.One.MouseButton1Down:Connect(function()
	game:GetService("RunService").RenderStepped:Connect(function()
		local mousePos = Vector2.new(mouse.X, mouse.Y)
		local magnitudeBetween = (script.Parent.One.AbsolutePosition - mousePos).Magnitude
		local firstButtonAbsolutePosition = script.Parent.One.AbsolutePosition
		script.Parent.Frame.Size = UDim2.fromOffset(magnitudeBetween, 10)
		script.Parent.Frame.Position = UDim2.fromOffset(firstButtonAbsolutePosition.X, firstButtonAbsolutePosition.Y)
	end)
end)

Desired Effect:


Current:

If anyone knows the proper math needed to achieve this effect I would appreciate a point in the right direction!

You should be able to do:

local diff = (script.Parent.One.AbsolutePosition - mousePos)
local angle = math.deg(math.atan2(diff.Y, diff.X))

It might have some small issues like rotation or it goes the wrong way but it should hopefully work

1 Like

The line is rotating from the midpoint and not the origin unfortunately.

You need to account for the position offset with the angle. Easiest way is to set the AnchorPoint to (0.5,0.5) on the frame and then make the position halfway between the corner and the mouse.

local lineTemplate = script.Parent.Frame
lineTemplate.AnchorPoint = Vector2.new(0.5,0.5)
local mouse = game.Players.LocalPlayer:GetMouse()

script.Parent.One.MouseButton1Down:Connect(function()
	game:GetService("RunService").RenderStepped:Connect(function()
		local mousePos = Vector2.new(mouse.X, mouse.Y)
		local magnitudeBetween = (script.Parent.One.AbsolutePosition - mousePos).Magnitude
		local firstButtonAbsolutePosition = script.Parent.One.AbsolutePosition
		
		local diff = (script.Parent.One.AbsolutePosition - mousePos)
		local angle = math.deg(math.atan2(diff.Y, diff.X))
		
		lineTemplate.Size = UDim2.fromOffset(magnitudeBetween, 10)
		lineTemplate.Position = UDim2.fromOffset(firstButtonAbsolutePosition.X - diff.X/2 , firstButtonAbsolutePosition.Y - diff.Y/2)
		lineTemplate.Rotation = angle
	end)
end)
3 Likes

Works perfectly, thank you very much!

Hey again, one more issue. For whatever reason my line is not matchning up with the origin frame, represented by the red dots in this picture:
image
The actual end of the line is offset from the mouse, and the line’s origin does not match up with red dot, and is instead offset to the top of the frame. Here is the general layout of everything, with properties as well.
image
image
image
image

Wow this really seems like a bug in the AbsolutePosition. Based on the documentation it should account for the Anchor Point, but does not. You have to manually account for the anchor. Note also in this code, the order of the calculations has to change to use the adjusted point.

local mousePos = Vector2.new(mouse.X, mouse.Y)
			local firstButtonAbsolutePosition = script.Parent.One.AbsolutePosition +
				Vector2.new(
					(script.Parent.One.AnchorPoint.X * script.Parent.One.AbsoluteSize.X),
					(script.Parent.One.AnchorPoint.Y * script.Parent.One.AbsoluteSize.Y)
				)
			local magnitudeBetween = (firstButtonAbsolutePosition - mousePos).Magnitude

			local diff = (firstButtonAbsolutePosition - mousePos)
			local angle = math.deg(math.atan2(diff.Y, diff.X))

			lineTemplate.Size = UDim2.fromOffset(magnitudeBetween, 10)
			lineTemplate.Position = UDim2.fromOffset(firstButtonAbsolutePosition.X - diff.X/2 , firstButtonAbsolutePosition.Y - diff.Y/2)
			lineTemplate.Rotation = angle

Actually, it wasn’t accounting for the offset of a topbar on the UI. Adding the value of this offset to the Y value of the position fixed it!