I am creating a system that can map plants in patches around a sphere, which is a planet. It works very well, but as the system keeps going, it starts changing the lookvector, idk why, and the plants start hovering off of the planet. This is bad.
You can see hovering on the grass if you look closely at the edges. Can someone help?
Code:
local function patch(amount)
local lastPosition = nil
local rightVector = nil
local upVector = nil
for i = 1, amount do
throttle += 1
if throttle == 20 then
task.wait()
throttle = 0
end
local phi = math.random() * math.pi
local theta = math.random() * 2 * math.pi
local x = Variables.Radius * math.sin(phi) * math.cos(theta)
local y = Variables.Radius * math.sin(phi) * math.sin(theta)
local z = Variables.Radius * math.cos(phi)
local myModel = createAlienPlant(height, density):Clone()
-- Adjust the Y component to spawn above the planet based on the distance
local position = Variables.Center + Vector3.new(x, y, z)
if lastPosition == nil then
rightVector = myModel.PrimaryPart.CFrame.RightVector
upVector = myModel.PrimaryPart.CFrame.UpVector
lastPosition = position
else
position = lastPosition + (rightVector * math.random(-100, 100)) + (upVector * math.random(-100, 100))
lastPosition = position
end
myModel.Parent = game.ReplicatedStorage.UnloadedPlants
myModel:PivotTo(CFrame.new(position, Variables.Center))
rightVector = myModel.PrimaryPart.CFrame.RightVector
upVector = myModel.PrimaryPart.CFrame.UpVector
--myModel:ScaleTo(ScaleFactor)
end
end
I am not sure of the method that you’ve used is valid for this usage but if I were to randomize the position of trees in a sphere, I would do it with Vector Addition methods such as Triangle or Parallelogram method, ( Polygon method wont work here since sphere doesn’t have vertices ).
This is a rough method that I did while reading your issue. The image is of 2 dimensional only so in order to make it 3D, you can count in the k vector i.e z-axis and find the Resultant Vector ( R ). With the help of all three vectors, you should be able to place the trees within that boundary.
[NOTE : using this method will leave some gaps which cannot be altered or changed so as to fill them up with plants or etc. ]
I am pretty sure if you use this method and combine it otherwise you can use the formula
|a||b| = (a.b) / (cos theta) where |a| and |b| represent magnitude of vectors A and B. (a.b) is dot product of the two vectors. cos theta is the angle between two vectors.
once you get the magnitudes, you can randomize them from lowest to maximum, clone the plant and place it there with the common Y-axis of all three vectors.
Yes, but the problem is not with random placement, its with placing random patches of foliage. My code works fine to place objects at random locations on the sphere. Also, math is not my best subject, so I dont really know how to implement your system.
If you’re really sure that your method is an apt way to go with this problem then one of the magnitude of a coordinate axis is being wrongly calculated in the script. Maybe print all the values and then have a dry run of it to see where possibly your code is going incorrect.
Otherwise, you can use my method as it only involves finding magnitude of 2 vectors and resultant vector.
local function randomPointOnSphere(center, radius)
local randomX = (math.random()*2)-1
local randomY = (math.random()*2)-1
local randomZ = (math.random()*2)-1
local randomVector = Vector3.new(randomX, randomY, randomZ)
local randomDirection = randomVector.Unit
local randomDirectionWithRadius = randomDirection * radius
local randomPointOnSurface = center + randomDirectionWithRadius
-- Adjust the randomPointOnSurface to prevent clipping inside the planet
local distanceToSurface = (randomPointOnSurface - center).Magnitude - radius
randomPointOnSurface = randomPointOnSurface - randomDirectionWithRadius.Unit * distanceToSurface
return randomPointOnSurface, randomDirection -- Return the random direction as well
end
local function spawnPartsAroundSphere(spherePart, numParts)
local radius = spherePart.Size.X / 2
local center = spherePart.Position
for i = 1, numParts do
local randomPoint, randomDirection = randomPointOnSphere(center, radius) -- Get the random direction from the randomPointOnSphere function
local part = game.ReplicatedStorage.Core:Clone()
part.Position = randomPoint
part.Parent = workspace
-- Rotate the part to face towards the center of the sphere
part.CFrame = CFrame.lookAt(part.Position, center)
end
end
while true do
wait(20)
spawnPartsAroundSphere(script.Parent, 5)
end
@sussy_bacoo and @Super_pro322222, this is not the problem. I can easily spawn the plants randomly around the planet. That works perfectly. The problem is spawning them in clumps, and still have them relative to the sphere. Raycasting is difficult, because I can’t just change the y value down a bit.