Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Can't figure out the math to make GUI frames appear in a circle?

Asked by 5 years ago

I am trying to make a GUI mini game where there is a circle with frames at random points on it. At the moment I am just trying to get the frames to make a full circle first so I can have something to start working off of to make if function properly

Here is the code I have put it a Script in a GUI as this portion is only the set up and has nothing to do with any mechanics apart from making a circle.

The commented out code was my first attempt in which is cause randomized frames off the GUI

local frame = script.Parent["Frame Spot"]
local messedup = false
local place = Instance.new("Frame")
place.Size = UDim2.new(0.046, 0,0.083, 0)
place.Position = UDim2.new(0.475, 0,0.042, 0)
place.Parent = frame
place.Name= "Place"
place.BackgroundColor3 = Color3.fromRGB(0,0,255)
place.BackgroundTransparency = 0.5
local count = 360

for i=1, count do
    local dec =  math.random(1,100)/100
    local angle =dec*math.pi*2
    local radius = frame.AbsolutePosition.X/3.4
    local x0 = frame.AbsolutePosition.X/2
    local y0 = frame.AbsolutePosition.Y/2.1
--  local x = (math.cos(angle)*radius)/frame.AbsolutePosition.X+0.4
--  local y = (math.sin(angle)*radius)/frame.AbsolutePosition.Y+0.4
    local x = x0+radius*math.cos(2*math.pi*i/count)-50
    local y = y0+radius*math.sin(2*math.pi*i/count)-17
    local marker = Instance.new("Frame")
          marker.Size = UDim2.new(0.046, 0,0.083, 0)
          marker.Position = UDim2.new(0, x,0, y)
          marker.Rotation = angle 
          marker.Name = "Test"
          marker.BackgroundColor3 = Color3.fromRGB(0,0,255)
          marker.BackgroundTransparency = 0.5
          marker.Parent = frame
end

At the moment what this code currently does is generate a rough circle but the frames make like an oval shape and just barely miss making a full circle and I am unsure of how I can make them actually turn it into a proper circle as all my attempts have made it much worse

I am using a image to have the frames line up on which is this https://www.roblox.com/library/3452386899/Images-Repair-minigame

If you need any more information feel free to ask for it and I will supply it to the best of my ability.

0
Thank you I will take a look at it deth836231 142 — 5y
0
Can you try setting `marker.Size` to have absolute pixel values instead of scaled values? If your `frame` isn't a square, then this may explain why they aren't forming a perfectly circle: they are being stretched. gskw 1046 — 5y
0
Ahh that makes sense I will try that deth836231 142 — 5y

1 answer

Log in to vote
1
Answered by 5 years ago

Not bad! However, this isn't the best way to do it: Instead of brute forcing the circle, you could is make it so that the circle is made up of rotated rectangles that meet on their ends, not unrotated squares. This is more efficient, and looks better overall. Here is your code modified to do that:

--Set Variables
local parentFrame = script.Parent["Frame Spot"]
local resolution = 50 --How many segments will make up the circle
local circleThickness = 500 --Thickness (in px)

--Calculated Variables
local diameter = math.min(parentFrame.AbsoluteSize.X, parentFrame.AbsoluteSize.Y) --Make the diameter the smallest frame dimention
local radius = diameter/2
local centerPos = (parentFrame.AbsoluteSize/2) --Center position of the frame
local markerWidth = math.asin((math.pi/resolution)) * radius * 2 --Width of the marker to make a seamless circle
circleThickness = math.clamp(circleThickness, 0, radius) --Clamp the thickness to a solid circle

for i=0, resolution do
    local radians = (2 * math.pi * i) / resolution --Convert our index to radians (A measure of rotation like degrees)
    local degrees = 360 * i / resolution --Also convert index to degrees
    --Marker pos is +/- center pos, so is added on. Offset B/C we want to align outside, so subtract off half of thickness
    local markerPos = centerPos + Vector2.new(math.cos(radians)*(radius - circleThickness/2), math.sin(radians)*(radius - circleThickness/2))   
    local markerAngle = degrees
    local marker = Instance.new("Frame")
          marker.Size = UDim2.new(0, circleThickness, 0, markerWidth + 1)
          marker.Position = UDim2.new(0,markerPos.X,0,markerPos.Y) 
          marker.Rotation = markerAngle 
          marker.Name = "Test"
          marker.AnchorPoint = Vector2.new(0.5, 0.5) --IMPORTANT: Set anchor point to center of frame
          marker.BackgroundColor3 = Color3.new(math.random(), math.random(), math.random())
          --marker.BackgroundTransparency = 0.5
          marker.BorderSizePixel = 0
          marker.Parent = parentFrame
Ad

Answer this question