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.
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
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
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
This is an output using magnitude, and it also uses the same random output as the image showing clusters.
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
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.
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!