local UserInputService = game:GetService("UserInputService") local RunService = game:GetService("RunService") local isDrawing = false local points = {} -- Accuracy tuning parameters (you can adjust these) local LINE_THRESHOLD = 20 -- Lower = more sensitive for detecting straight lines local CIRCLE_RADIUS_DEVIATION = 30 -- Lower = more sensitive for detecting perfect circles local RIGHT_ANGLE_THRESHOLD = 40 -- Tolerance for detecting right angles (in degrees) local MIN_TURN_ANGLE = 40 -- Minimum angle considered a "turn" for polygon detection local POLYGON_ANGLE_THRESHOLD = 30 -- Tolerance for angle deviation in polygons -- Start drawing when mouse button is pressed UserInputService.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 then isDrawing = true points = {} -- Reset points end end) -- Track mouse movement while drawing UserInputService.InputChanged:Connect(function(input) if isDrawing and input.UserInputType == Enum.UserInputType.MouseMovement then local mousePosition = input.Position table.insert(points, Vector2.new(mousePosition.X, mousePosition.Y)) end end) -- Stop drawing and analyze points when mouse button is released UserInputService.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 then isDrawing = false detectShape(points) end end) -- Function to detect the shape function detectShape(points) if #points < 10 then print("Too few points to detect a shape.") return end local firstPoint = points[1] local lastPoint = points[#points] -- Check if the first and last points are close (to form closed shapes) local distance = (firstPoint - lastPoint).Magnitude if distance < 50 then if isCircle(points) then print("Circle detected!") elseif isSquare(points) then print("Square/Rectangle detected!") elseif isTriangle(points) then print("Triangle detected!") elseif isPolygon(points) then print("Polygon detected!") else print("Unknown closed shape") end else if isLine(points) then print("Line detected!") else print("Unknown open shape") end end end -- Helper function to check if the points form a line function isLine(points) local totalLength = 0 local directLineLength = (points[1] - points[#points]).Magnitude for i = 2, #points do totalLength = totalLength + (points[i] - points[i - 1]).Magnitude end -- If the total length of the segments is almost equal to the direct line distance, it's a line return math.abs(totalLength - directLineLength) < LINE_THRESHOLD end -- Helper function to check if the points form a circle function isCircle(points) local center = (points[1] + points[#points]) / 2 local totalRadius = 0 local radiusDeviation = 0 -- Calculate the average radius from the center for _, point in ipairs(points) do local radius = (point - center).Magnitude totalRadius = totalRadius + radius end local averageRadius = totalRadius / #points -- Calculate the deviation from the average radius for _, point in ipairs(points) do local radius = (point - center).Magnitude radiusDeviation = radiusDeviation + math.abs(radius - averageRadius) end -- If the deviation is small, it's a circle return radiusDeviation / #points < CIRCLE_RADIUS_DEVIATION end -- Helper function to check if the points form a square or rectangle function isSquare(points) local function getAngle(v1, v2) return math.acos(v1:Dot(v2) / (v1.Magnitude * v2.Magnitude)) end local rightAngleCount = 0 local turns = 0 -- Check for 90-degree turns (right angles) for i = 2, #points - 1 do local v1 = (points[i] - points[i - 1]).Unit local v2 = (points[i + 1] - points[i]).Unit local angle = getAngle(v1, v2) -- 90-degree turns (right angle) if math.abs(math.deg(angle) - 90) < RIGHT_ANGLE_THRESHOLD then rightAngleCount = rightAngleCount + 1 end -- Track major turns if math.deg(angle) > MIN_TURN_ANGLE then turns = turns + 1 end end -- A square/rectangle usually has 4 right angles and exactly 4 turns return rightAngleCount >= 3 and turns == 4 end -- Helper function to check if the points form a triangle function isTriangle(points) local function getAngle(v1, v2) return math.acos(v1:Dot(v2) / (v1.Magnitude * v2.Magnitude)) end local turns = 0 -- Check for 3 major turns to detect a triangle for i = 2, #points - 1 do local v1 = (points[i] - points[i - 1]).Unit local v2 = (points[i + 1] - points[i]).Unit local angle = getAngle(v1, v2) -- If the angle between segments indicates a sharp turn, increment if math.deg(angle) > MIN_TURN_ANGLE then turns = turns + 1 end end -- A triangle has exactly 3 turns (corners) return turns == 3 end -- Helper function to check if the points form a polygon (with more than 4 sides) function isPolygon(points) local function getAngle(v1, v2) return math.acos(v1:Dot(v2) / (v1.Magnitude * v2.Magnitude)) end local turns = 0 local angleSum = 0 local angles = {} -- Measure all angles between points for i = 2, #points - 1 do local v1 = (points[i] - points[i - 1]).Unit local v2 = (points[i + 1] - points[i]).Unit local angle = math.deg(getAngle(v1, v2)) if angle > MIN_TURN_ANGLE then table.insert(angles, angle) turns = turns + 1 end end -- Check if all angles are roughly the same for a regular polygon if #angles >= 4 then local averageAngle = 0 for _, angle in ipairs(angles) do averageAngle = averageAngle + angle end averageAngle = averageAngle / #angles -- Check if the deviation from the average angle is small local deviation = 0 for _, angle in ipairs(angles) do deviation = deviation + math.abs(angle - averageAngle) end -- If deviation is small, it's likely a regular polygon return deviation / #angles < POLYGON_ANGLE_THRESHOLD end return false end