Broken Circles Needing a fix

Hello, I want to have a circle function that creates a circle using the perfect amount of parts. I think I have gotten the right amount of parts just not in the right location. I got the circumference of my circle and did a for loop divided by the parts size. I believe this give the correct amount of parts. I then just used sin and cos to get the location of the parts but it gives this result.

Here is my code

local Radius = 100
local Circumference = 2 * math.pi * Radius

for Index = 1, Circumference / 2.5 do
	local Part = Instance.new("Part")
	Part.CFrame = CFrame.new(0, Radius * math.sin(Index), Radius * math.cos(Index))
	Part.Anchored = true
	Part.Size = Vector3.new(2.5, 2.5, 2.5)
	Part.Parent = workspace
end

How can I make it so they do not form in little groups and for gaps? All while using just the right amount of parts, so basically the parts are just barely touching like this:

But in a circle formation like in the image above?

All help would be appreciated thanks!

1 Like

The problem is that you are taking the sine and cosine of a value that is an arc length, and not an angle. So basically, your code creates multiple circles that are offset from each other, because the Index variable exceeds 2 * math.pi multiple times. I made some changes to your code visualize this. The layers variable refers to the amount of circles created. The parts are colored based on which circle they belong to. I also added a wait in the loop so that you can more accurately see what’s happening.

local Radius = 100
local Circumference = 2 * math.pi * Radius

local layers = math.ceil(Circumference / (2.5*math.pi*2))
local currentLayer = 0
local parts = 0

wait(3)

for Index = 1, Circumference / 2.5 do
	local Part = Instance.new("Part")
	Part.CFrame = CFrame.new(0, Radius * math.sin(Index), Radius * math.cos(Index))
	Part.Anchored = true
	Part.Size = Vector3.new(2.5, 2.5, 2.5)
	Part.Parent = workspace
	
	
	local layer = math.floor(Index / (math.pi * 2))
	local val = layer / layers
	Part.Color = Color3.new(val, val, val)
	
	parts += 1
	print(parts)
	if layer > currentLayer then
		currentLayer += 1
		wait(1.5)
	end
end

Here’s an image of the final result with this edited code.

One thing you could do to is this.

local RADIUS = 100

local PART_SIZE = 2.5

local circumference = 2 * math.pi * RADIUS
local numOfPArts = math.ceil(circumference / PART_SIZE)

for i = 1, numOfPArts do
	local angle = i / numOfPArts * math.pi * 2
	local Part = Instance.new("Part")
	Part.CFrame = CFrame.new(0, RADIUS * math.sin(angle), RADIUS * math.cos(angle))
	Part.Anchored = true
	Part.Size = Vector3.new(PART_SIZE, PART_SIZE, PART_SIZE)
	Part.Parent = workspace
end

However, although it gets rid of the gaps, the parts still overlap. Here’s an image.

If you want to make a circle using non-rotated parts, and don’t want gaps or overlapping parts, the code below may give you the result you want. It calculates the y positions for about one eighth of the circle and then mirrors the (x, y) position to create the rest of the circle.

local RADIUS = 100

local PART_SIZE = 2.5

local partRadius = RADIUS/PART_SIZE

local partFolder = Instance.new("Folder")
partFolder.Name = "xDeltaXenCircle"
partFolder.Parent = workspace

local function createPart(x, y)
	local part = Instance.new("Part")
	part.Position = Vector3.new(x * PART_SIZE, y * PART_SIZE, 0)
	part.Anchored = true
	part.Size = Vector3.new(PART_SIZE, PART_SIZE, PART_SIZE)
	part.Parent = partFolder
end

for x = 1, partRadius * math.sin(math.pi/4) do
	local y = math.floor(math.sqrt(partRadius^2 - x^2))
	for xm = -1, 1, 2 do
		for ym = -1, 1, 2 do
			local xOffset, yOffset = x * xm, y * ym
			createPart(xOffset, yOffset)
			if y > x then
				createPart(yOffset, xOffset)
			end
		end
	end
end
createPart(partRadius, 0)
createPart(-partRadius, 0)
createPart(0, partRadius)
createPart(0, -partRadius)

Here’s an image.

2 Likes

I tried to play around and got this. (higher radius better look lol)

local XZSize, YSize = 2.5, 2.5;
local Radius = 100;

local PartSize = Vector3.new(XZSize,YSize,XZSize);
local NumberOfParts = Radius*(PartSize.X+PartSize.Y)/2;

local function CreatePart()
	local Part = Instance.new('Part');
	Part.Anchored = true;
	Part.Parent = workspace.Circle;
	Part.Size = PartSize;
	return Part;
end;

for i = 1, NumberOfParts do
	local Part = CreatePart();
	local Angle = (math.pi*2/NumberOfParts)*i;
	local X, Z = math.cos(Angle)*Radius, math.sin(Angle)*Radius;
	Part.Position = Vector3.new(X,0,Z);
end;