How to get the area of a circle

Hi, I have a script that is supposed to spawn spikes and it works. There is a Random X and Y coordinate in that script and these coordinates are the position of the spike where it needs to be placed. But my platform is a circle. That means the spikes are spawning outside the circle sometimes because the random coordinates create a square and thats why the spikes can spawn outside the circle platform.

Here´s a picture that explains the problem better:

I wonder how I can make the script know that it needs to spawn in the circle. Here´s the currently part of the script:

local RandomX = math.random(-80, 80)
local RandomY = math.random(-80, 80)
local bakedVector = Vector3.new(RandomX, 0, RandomY)
WarnPart.Position = game.Workspace.Boss1.HumanoidRootPart.Position - Vector3.new(0, 17.5, 0) + bakedVector

If it´s possible, does anybody know how I can code something to make the spikes spawn inside the circle? Do I need the surface area of the circle like: A = π * r² ? Or the scope like: R = 2 * r * π ? Or do I need something completely diffrent like something that I dont know about? Theres something called surface in roblox studio and I dont know if I need that.

I would appreciate anyone who can help me.

1 Like

5th to 6th grade’s math. You multiply π (3.14) with the radius (r) of the circle.

Radius being the size of the cylinder/2. Also your formula is incorrect:

πr²

3 Likes

I know that but if I try to add it into the script it still has the shape of a square

I wrote A = pi * r² thats the same. A means surface area and the * symbol is hidden between pi and r²

You could check the magnitude from the spawn location to the center of the circle, and if the magnitude is too large, select a new random location.

1 Like

It would be something like this:

A = math.pi * (r * r)
local RandomX = math.random(-80, 80)
local RandomY = math.random(-80, 80)
local position = r * Vector3.new(
     math.cos(RandomX)*math.cos(RandomY),
     math.sin(RandomY), 
     math.sin(RandomX)*math.cos(RandomY)
) + Sphere.Position

3 Likes

Simple vector maths for this method, just do:

local centrePos = Vector2.new(-- Put the X and Y coordinates of the centre here)
local maxDistance = 60 -- In studs

local bakedVector

while not bakedVector do
    -- Produces a square-bound position
    local randomX = math.random(-maxDistance,maxDistance)
    local randomY = math.random(-maxDistance,maxDistance)
    local randomPos = Vector2.new(randomX,randomY)

    local magnitude = (centrePos - randomPos)
    -- Checks if it also fits in the circle
    if magnitude.X < maxDistance and magnitude.Y < maxDistance then
        if magnitude.X > -maxDistance and magnitude.Y > -maxDistance then
            -- Nested to make it easier to read
            bakedVector = Vector3.new(magnitude.X,0,magnitude.Y)
        end
    end
end

Written from memory and docs reference, excuse any errors.
Edit: Forgot about possible negative magnitudes lol

1 Like

@kalabgs
I tried your code and it gave this result

image

why do they end up sorted into rings?

The math.random() outputs integers, not floats. This means they don’t fill the entire circle, just the areas where X and Y is an integer.

1 Like

local R = Random.new():NextNumber(Min,max)

use that to get the random number instead

1 Like

the RandomX and RandomY correspondent to longitude and latitude, which in reality are angles.
Since this uses trigonometry to represent 2 circles and find a point from the angles, using real numbers makes no drastic changes.

i recommend using floats

local RandomX = math.random(-8000, 8000) / 1000
local RandomY = math.random(-8000, 8000) / 1000
1 Like

This is an output using magnitude, and it also uses the same random output as the image showing clusters.
image

if workspace:FindFirstChild("Spikes") then workspace.Spikes:Destroy() end
local dir = Instance.new("Folder")
dir.Name = "Spikes"
dir.Parent = workspace
local Sphere = workspace.Circle
for n = 1,2000 do
	local r = 80
	local spike = workspace.Spike:Clone()
	spike.Parent = dir
	local pos = Vector3.new(math.random(-r,r),0,math.random(-r,r))
	while pos.Magnitude> r do
		pos = Vector3.new(math.random(-r,r),0,math.random(-r,r))
	end

	spike:PivotTo(CFrame.new(pos+Sphere.Position)*CFrame.Angles(0,0,math.rad(90)) )
end

1 Like

It still seems to cluster

1 Like

longtitude and latitude just act that way. If you pick a random globe you will see that on the top, the latitude and longtitude lines cluster.
image

1 Like

I see, thank you so much for the explanation. Didn’t mean to keep this solved post going, I was just curious and wanting to sort of understand why the results looked like they do.

I appreciate it.
Thanks again.

1 Like

try doing something like this:

local middle = Vector3.new(0,0,0) --the middle of the circle
local maximum = 80 --maximum it can get offsetted
local RandomX = math.random(-maximum * 100, maximum * 100) / 100 --multiplied by 100 before picking a random number and then divides it by 100 again
local RandomY = math.random(-maximum * 100, maximum * 100) / 100
local bakedVector = Vector3.new(RandomX, 0, RandomY)

--now here comes the math
local result = bakedVector.Unit * math.min(bakedVector.Magnitude, maximum)
if result.X ~= result.X or result.Y ~= result.Y or result.Z ~= result.Z then --just incase one of the axes in result is nan 
	result = middle
end

Explanation:
backedVector.Unit edits the vector so that it’s magnitude always equals to 1
and then multiply the result by either backedVector.Magnitude or maximum. The smallest value gets chosen.
Before using the newly acquired vector, we have to check whether any of axes is a nan (not a number), which if we don’t, it might cause us big trouble. If any of them is a nan, we will just set the result to middle and with that out of the way, the vector should be hopefully successfully be clamped within the circle’s area! (unless there’s an error which I hope not…)

Also, the reason why I multiplied maximum by 100, but to only divide it by 100 again when getting a random number is so that the value is ‘more random’ if that makes any sense. math.random() only picks integers, so no rational numbers. By multiplying maximum by 100 before choosing a random integer, gives us a bigger number (for example: 7539) which we can divide by 100 afterwards to give us a rational number (using the example we get 75.39).

I put this code really quickly together, so I don’t think it’s going to work first try, but if it works, or there are any errosr, then you can ask me and I’ll try to find a solution! :+1:

1 Like

What is the “r” ?! You should put a variable.

This is a solved post, for future reference dm the post creator. r would be the radius of the circle