To accomplish this, I would first choose a random point on the outside of the rectangular bounds. Then I would calculate the distance from the origin to the chosen point and generate a random number between the distance found and the maximum distance (circle radius). Then the random point inside the volume would be the unit vector (direction) of the point times the random distance plus your offset.
local function randPos(origin, bounds, maxDist)
local face = math.random(0, 5)
local axis = face%3
local x, y, z
if axis == 0 then
x = face > 2 and -bounds.X/2 or bounds.X/2
y = math.random()*bounds.Y - bounds.Y/2
z = math.random()*bounds.Z - bounds.Z/2
elseif axis == 1 then
x = math.random()*bounds.X - bounds.X/2
y = face > 2 and -bounds.Y/2 or bounds.Y/2
z = math.random()*bounds.Z - bounds.Z/2
else
x = math.random()*bounds.X - bounds.X/2
y = math.random()*bounds.Y - bounds.Y/2
z = face > 2 and -bounds.Z/2 or bounds.Z/2
end
local point = Vector3.new(x, y, z)
local dist = point.magnitude
local r = math.random()*(maxDist - dist) + dist
return origin + point.unit*r
end
Here is a usage example:
local origin = Vector3.new(0, 20, 0)
local bounds = Vector3.new(10, 10, 10)
local maxDist = 15
local part = Instance.new("Part")
part.Anchored = true
part.BrickColor = BrickColor.new("Eggplant")
part.Size = Vector3.new()
part.Parent = game.Workspace
while wait(0.5) do
part.CFrame = CFrame.new(randPos(origin, bounds, maxDist))
end
###Edit
Turns out I misread your question, This calculates a random position in a sphere out side of a 3D bounds. Calculating this is 2D simplifies the problem and you can use the same approach:
local function randPos(origin, bounds, maxDist)
local edge = math.random(0, 3)
local axis = edge%2
if axis == 0 then
x = edge > 2 and -bounds.X/2 or bounds.X/2
z = math.random()*bounds.Z - bounds.Z/2
else
x = math.random()*bounds.X - bounds.X/2
z = edge > 2 and -bounds.Z/2 or bounds.Z/2
end
local point = Vector3.new(x, 0, z)
local dist = point.magnitude
local r = math.random()*(maxDist - dist) + dist
return origin + point.unit*r
end
Usage Example:
local origin = Vector3.new(0, 20, 0)
local bounds = Vector3.new(10, 0, 10)
local maxDist = 15
part.CFrame = CFrame.new(randPos(origin, bounds, maxDist))
1 comment
I fixed it myself but am curious to hear your guys' solutions, so if you want to post them below.