I’ve been trying to create a line that goes between two of my GUI objects to create sort of a trail. Each of my GUIs have an AnchorPoint of 0.5, 0.5, to make the line connect them by the middle points.
You should calculate the slope based on their absolute position instead of their scales. A screen that’s 2000x1000 pixels wide would throw your math off.
In addition, to what @XAXA said, use math.atan2 to calculate the angle. It’s a life-saver. From the Wiki:
math.atan2
number math.atan2(number y, number x)
Description: Returns the arc tangent of y/x (in radians), but uses the signs of both parameters to find the quadrant of the result. It also handles correctly the case of x being zero.
(in your case, the quadrant part of math.atan2 doesn’t affect much, but the handling x being zero part is nice)
Yes, the code I provided explicitly uses offsets. Your example uses scales. As someone already pointed out, using scales would not be effective as most screens are not squares and 1.0 across the X wouldn’t be the same as 1.0 across the Y.
local function DrawLine(from: Vector2, to: Vector2, options: { color: Color3 | nil, width: number | nil }): (Frame)
if not options then options = {} end
local distance = to - from
local line = Instance.new("Frame", script.Parent)
line.AnchorPoint = Vector2.new(0.5, 0.5)
line.BackgroundColor3 = options.color or Color3.fromRGB(255, 0, 0)
line.Rotation = math.atan2(distance.Y, distance.X) * (180 / math.pi)
line.Position = UDim2.fromOffset((to + from).X / 2, (to + from).Y / 2)
line.Size = UDim2.fromOffset((distance.X ^ 2 + distance.Y ^ 2) ^ 0.5, options.width == nil and 1 or options.width)
return line
end
local function DrawLineUI(guiObject1: GuiBase2d, guiObject2: GuiBase2d, options: { color: Color3 | nil, width: number | nil }): (Frame)
local from = guiObject1.AbsolutePosition + (guiObject1.AbsoluteSize * Vector2.new(0.5, 0.5))
local to = guiObject2.AbsolutePosition + (guiObject2.AbsoluteSize * Vector2.new(0.5, 0.5))
return DrawLine(from, to, options)
end
DrawLine(Vector2.new(100, 100), Vector2.new(200, 200), {color = Color3.fromRGB(0, 255, 0)}) -- Create a green line from (x: 100, y: 100) to (x: 200, y: 200)
-- Updated at 29/11/2023
-- typing added
-- 'options' added
For some odd reason, when I used this algorithm, it appeared as though the one line was not working as intended.
It wasn’t an error of arguments either, if I removed an instance causing the issue in the for loop, another line would be glitched in the same way. If you could help me understand what was causing the issue, it would be rather helpful. Here’s a screenshot of what it looks like.
local a = Mainframe.UDim2.toVector2(teamPositions[team1])
local b = Mainframe.UDim2.toVector2(teamPositions[team2])
if b.X < a.X then --a is always on left
local temp = a
a=b
b=temp
end
local barx,bary = Mainframe.midpoint(a.X, a.Y, b.X, b.Y)
bar.Size = UDim2.fromOffset(bar.Size.X.Offset, (a-b).Magnitude)
bar.Position = UDim2.new(0.5,barx,0.5,bary)
bar.Rotation = math.deg(math.atan2(bar.Position.Y.Offset,bar.Position.X.Offset))
This way of creating lines is a workaround, you must create a “correct” shape with the start position, the end position, and the size of the line, so you can do all the possible calculations (for example, calculate the intersection point)
(Take the CanvasContextRendering2D[web api] as an example)