Extend line past mouse but maintain position

I’m trying to get a line to extend past the mouse to the edge of a table. It works great when the mouse is outside the tables bounds, but when the mouse is on the table, it doesn’t extend as expected
robloxapp-20240518-1230440-ezgif.com-video-to-gif-converter

local TABLE_WIDTH = 30
local TABLE_HEIGHT = 60
local TABLE_POSITION = Vector3.new(0, 0, 0)
local TABLE_Y = 0

local function isWithinTableBounds(position)
	return math.abs(position.X) <= TABLE_WIDTH / 2 and math.abs(position.Z) <= TABLE_HEIGHT / 2
end

local function clampToTableBounds(position)
	local clampedX = math.clamp(position.X, -TABLE_WIDTH / 2, TABLE_WIDTH / 2)
	local clampedZ = math.clamp(position.Z, -TABLE_HEIGHT / 2, TABLE_HEIGHT / 2)
	return Vector3.new(clampedX, position.Y, clampedZ)
end

local function getMousePositionOnTable()
	local mouseScreenPos = UserInputService:GetMouseLocation()
	local mouseRay = Camera:ViewportPointToRay(mouseScreenPos.X, mouseScreenPos.Y)

	-- Calculate the intersection with the table plane (y = TABLE_Y)
	local direction = mouseRay.Direction
	local origin = mouseRay.Origin
	local t = (TABLE_Y - origin.Y) / direction.Y
	local intersection = origin + direction * t

	return intersection
end

local function getClampedMousePositionOnTable()
	local mousePositionOnTable = getMousePositionOnTable()
	if isWithinTableBounds(mousePositionOnTable) then -- Extend to table bounds
		mousePositionOnTable = Vector3.new(mousePositionOnTable.X * 10, mousePositionOnTable.Y, mousePositionOnTable.Z * 10)
	end
	
	local clampedPosition = clampToTableBounds(mousePositionOnTable)
	
	return clampedPosition
end

local lineSegment = HUD.Line

RunService.Heartbeat:Connect(function()
	local cueBallPosition = workspace["1"].Position
	local cueBallScreenPos, onScreen = Camera:WorldToViewportPoint(cueBallPosition)

	local clampedMousePositionOnTable = getClampedMousePositionOnTable()
	local clampedMouseScreenPos = Camera:WorldToViewportPoint(clampedMousePositionOnTable)

	local originX, originY = cueBallScreenPos.X, cueBallScreenPos.Y
	local endPointX, endPointY = clampedMouseScreenPos.X, clampedMouseScreenPos.Y

	local origin = Vector2.new(originX, originY)
	local endPoint = Vector2.new(endPointX, endPointY)
	local netVector = endPoint - origin

	local length = math.sqrt(netVector.X ^ 2 + netVector.Y ^ 2)
	local midpoint = Vector2.new((origin.X + endPoint.X) / 2, (origin.Y + endPoint.Y) / 2)
	local theta = math.deg(math.atan2(originY - endPointY, originX - endPointX))

	lineSegment.Position = UDim2.fromOffset(midpoint.X, midpoint.Y)
	lineSegment.Rotation = theta
	lineSegment.Size = UDim2.fromOffset(length, 6)
end)