- Home /
Sphere made of cubes algorithm
Hey guys! I'm looking for a simple (or less simple) algorithm, that will create a sphere made of cubes with some adjustable radius. Something like this for cube, but for sphere.
var prefab : Transform; var oneSide : int = 5; function Start(){ var x : int = 0; var y : int = 0; var z : int = 0; while(x
And I don't wan't to rotate the cubes to the center. :)
David
Answer by flaviusxvii · Jul 12, 2011 at 07:39 PM
The code you have will work, you just need to check to see if transform.position + Vector3(x,y,z) is in the target sphere, an only instantiate if it is.
If you want to find out if something is in a sphere, you can find the distance between the point in question and the centre of the sphere. If that is greater than the radius, it is no longer inside the sphere ...
(...if you're using centroids - if you're considering any point on your cube touching to be "in", there's more to do)
Thanks, worked.
var prefab : Transform; var size : int; var radius : float;
function Start() { var x : int = -size; var y : int = -size; var z : int = -size;
while(x
faster way of doing your distance check:
if (Vector3.Sqr$$anonymous$$agnitude(Vector3(x,y,z)) > (radius * radius))
because you only need to check the x/y/z Vector relative to 0 (and then place that at your transform).
Because 1) position - position + Vector3(x,y,z) == Vector3(x,y,z) ! 2) Comparing Sqr$$anonymous$$agnitude with a square of the radius is much faster
Answer by Peter G · Jul 12, 2011 at 06:28 PM
I haven't tried this, but this blog post seems to describe exactly what you want.
http://entitycrisis.blogspot.com/2011/02/uniform-points-on-sphere.html
Answer by Chris D · Jul 12, 2011 at 06:03 PM
While I'm thinking of a better (more efficient) option, why not find the (cubic) bounds of the sphere you want to convert, flood it with cubes of the resolution you want, then run a quick collision check to see which of the cubes are held within the sphere?
It seems like this would work but, again, I can't imagine it's the best way to go about it.
So (in 3d) you create your sphere. Then you create a larger box that contains its bounds, kind of like this:
SquareCircle: https://upload.wikimedia.org/wikipedia/commons/0/00/Square-circle.svg [preview of external content removed for GDPR compliance as it was including 3rd party cookies]
and you flood that cube with your smaller cubes (of the size you choose, with the code you already have, assu$$anonymous$$g it works) on a grid.
After that, you run a check to see which of those cubes intersects the sphere. If they don't, destroy them.
I'm not sure there's really one answer to this question...
Well I tried, that is it collides, than not destroy, is not destroy, but it isn't working :(. I suck at mesh thingys.
I don't understand what you're saying. You have code working but it's not destroying anything?
I tried, that if a cube is colliding with that sphere don't destroy and if it isn't than destroy, but it destroyed all cubes, I will try that distance, that was posted below :)
Answer by BillyBobBeavis · Jun 14, 2021 at 01:40 AM
This solution worked for me. As said above you can make a cubical grid and check distance from a center point. This code makes a sphere of cubes that looks like something from MineCraft, but the idea is the same, just delete all the components from the brick and you have a grid of transforms. If you just want the shell of the sphere add a minimum distance in the distance check. You might want to reduce the number of bricks though. I'm running this on a 1060 GPU and I'm only getting a few frames.
public GameObject brick;
public int gridWidth;
public int gridDepth;
public int gridHeight;
public List<GameObject> gridElements;
public GameObject gridCenter;
public Bounds gridBounds;
void Start()
{
gridWidth = 240;
gridDepth = 240;
gridHeight = 240;
gridCenter = new GameObject();
brick = GameObject.CreatePrimitive(PrimitiveType.Cube);
brick.transform.localScale = new Vector3(6, 6, 6);
for (int y = 0; y < gridHeight; y = y + 6)
{
for (int z = 0; z < gridDepth; z = z + 6)
{
for (int x = 0; x < gridWidth; x = x + 6)
{
var gridElement = Instantiate(brick, new Vector3(x, y, z), Quaternion.identity);
gridElements.Add(gridElement);
gridBounds.Encapsulate(gridElement.transform.position);
}
}
}
Destroy(brick);
gridCenter.transform.position = gridBounds.center;
foreach(GameObject gridElement in gridElements)
{
var distance = Vector3.Distance(gridElement.transform.position, gridCenter.transform.position);
if (distance > 120)
Destroy(gridElement);
else
gridElement.transform.parent = gridCenter.transform;
}
gridCenter.transform.position = new Vector3(0, 0, 0);
}