Jump to content

[1.7.10] Generating a sphere


The_SlayerMC

Recommended Posts

Hey, im trying to generate spheres for my dimension, but i cant quite get the sphere shape, all i can get is this: http://prntscr.com/4xam3y

 

As you can tell, its making a circle shape but its turning out to be just a 1x block thick platform

 

This is the code i wrote:

int radius = 8;
		for(float i = 0; i < radius; i += 0.5) {
			for(float j = 0; j < 2 * Math.PI * i; j += 0.5)
				w.setBlock((int)Math.floor(x + Math.sin(j) * i), y + radius, (int)Math.floor(z + Math.cos(j) * i), Blocks.bedrock);
		}

 

Whats the most efficient way to generate a sphere (a whole depth sphere)

Former developer for DivineRPG, Pixelmon and now the maker of Essence of the Gods

Link to comment
Share on other sites

Hi

 

The easiest way is to iterate over a cube  and for each [x,y,z], calculate the squared distance to the centre of the circle.  If it's less than the squared radius, it's in the sphere.  If more, it's outside.

 

eg

for x = centre minus radius to centre plus radius

  for y = centre minus radius to centre plus radius

    for z = centre minus radius to centre plus radius {

squareDistance = (x-centre)^2 + (y-centre)^2 + (z-centre)^2

if squareDistance <= (sphere radius)^2 then set block stone

 

}

 

Don't worry about being efficient.  Java is so fast you'll never notice the difference no matter how much you optimise it.

 

 

-TGG

Link to comment
Share on other sites

Don't worry about being efficient.  Java is so fast you'll never notice the difference no matter how much you optimise it.

 

I used to think that, but I've been doing a lot with structure generation lately and found that with very simple code (just loop through an array and place bocks indicated) it can create perceptible lag on structures of any decent size.  I actually changed my code to only do one layer per tick in order to improve this.

 

I think a sphere the size he's showing could actually show a bit of lag.  Generally though that won't be too noticeable if it happens during chunk generation because players are used to some lag from that, but if you generate the structure in response to player action (like using a tool), it can be noticeable.

 

Anyway, I was surprised that it could lag, but I think the thing is that the volume of a structure gets large very fast -- a sphere as large as shown in the OP's picture has 5000 blocks!  And I think the block placement requires fair bit of processing as well as client server sync notification.  Just giving my observation...

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

I agree a bit, using the code he provided I tried to create a 15 radius sphere, took 2 secs to generate. But yeah, even with the most optimized code snippet ever, that amount of blocks is still going to take a bit to generate.. this is what I think of it, so yeah, you both are right

I try my best, so apologies if I said something obviously stupid!

Link to comment
Share on other sites

I agree a bit, using the code he provided I tried to create a 15 radius sphere, took 2 secs to generate. But yeah, even with the most optimized code snippet ever, that amount of blocks is still going to take a bit to generate.. this is what I think of it, so yeah, you both are right

 

Yeah. What I ended up doing was to actually have my Y index increment over each tick, rather than loop through all Y in one tick.  That kind of spreads the lag.  I previously made it only do one dimension at a time per tick (i.e. both the Y and Z loops were incremented over ticks rather than within a tick) but at that point the total time to make the structure gets pretty long -- a 20 diameter sphere would take 400 ticks = 20 seconds.  Which was too long, but the good thing was there was no lag at all.  So it seems to be a balance.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Noob question, I haven't tried this before: could you generate a structure in a separate thread?

 

I think I tried that and got concurrency errors.  I'm not expert at threads, but unless you design the threads to work together you get into trouble if two threads are trying to operate on the same data -- i.e. think of one thread trying to read the array of the blocks in the world at the same time the other thread is trying to place a new block.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Hi

 

The easiest way is to iterate over a cube  and for each [x,y,z], calculate the squared distance to the centre of the circle.  If it's less than the squared radius, it's in the sphere.  If more, it's outside.

 

eg

for x = centre minus radius to centre plus radius

  for y = centre minus radius to centre plus radius

    for z = centre minus radius to centre plus radius {

squareDistance = (x-centre)^2 + (y-centre)^2 + (z-centre)^2

if squareDistance <= (sphere radius)^2 then set block stone

 

}

 

Don't worry about being efficient.  Java is so fast you'll never notice the difference no matter how much you optimise it.

 

 

-TGG

 

Thanks! But can i make it so it generates random sized ones aswell?

Former developer for DivineRPG, Pixelmon and now the maker of Essence of the Gods

Link to comment
Share on other sites

I tried this just for a normal one:

 

int radius = 8;
		int centre = radius / 2, squareDistance = 0;
		for(x = centre - radius; x < centre + radius; x++)
			for(y = centre - radius; y < centre + radius; y++)
				for(z = centre + radius; z < centre + radius; z++) {
					squareDistance = (x-centre)^2 + (y-centre)^2 + (z-centre)^2;
					/*if(squareDistance <= (radius)^2)*/ w.setBlock(x, y, z, Blocks.bedrock);

				}

 

But nothing is seeming to generate at all

Former developer for DivineRPG, Pixelmon and now the maker of Essence of the Gods

Link to comment
Share on other sites

Don't worry about being efficient.  Java is so fast you'll never notice the difference no matter how much you optimise it.

 

I used to think that, but I've been doing a lot with structure generation lately and found that with very simple code (just loop through an array and place bocks indicated) it can create perceptible lag on structures of any decent size.  I actually changed my code to only do one layer per tick in order to improve this.

 

I think a sphere the size he's showing could actually show a bit of lag.  Generally though that won't be too noticeable if it happens during chunk generation because players are used to some lag from that, but if you generate the structure in response to player action (like using a tool), it can be noticeable.

 

Anyway, I was surprised that it could lag, but I think the thing is that the volume of a structure gets large very fast -- a sphere as large as shown in the OP's picture has 5000 blocks!  And I think the block placement requires fair bit of processing as well as client server sync notification.  Just giving my observation...

Hi Jabelar

I agree with you, it will take a long time to place that many blocks.  I'm just about to release a mod that copies up to 256x256x256 blocks and it can take up to a minute or more.

 

What I meant was - I've seen other folks try to optimise out some of the "squareDistance" checks.  That's a total waste of mental effort.

 

-TGG

 

 

Link to comment
Share on other sites

I tried this just for a normal one:

 

int radius = 8;
		int centre = radius / 2, squareDistance = 0;
		for(x = centre - radius; x < centre + radius; x++)
			for(y = centre - radius; y < centre + radius; y++)
				for(z = centre + radius; z < centre + radius; z++) {
					squareDistance = (x-centre)^2 + (y-centre)^2 + (z-centre)^2;
					/*if(squareDistance <= (radius)^2)*/ w.setBlock(x, y, z, Blocks.bedrock);

				}

 

But nothing is seeming to generate at all

 

Ah, I think I might have confused you.

 

When I wrote ^2 I meant 'squared', but that's not what the ^ operator does in Java.

 

Try this instead

squareDistance = (x-centre)*(x-centre) + (y-centre)*(y-centre) + (z-centre)*(z-centre);

 

You've got a typo here which is probably causing your problem

 

for(z = centre + radius

 

-TGG

 

Link to comment
Share on other sites

So now i've got this:

 

int radius = 8;
		int centre = radius / 2, squareDistance = 0;
		for(x = centre - radius; x < centre + radius; x++)
			for(y = centre - radius; y < centre + radius; y++)
				for(z = centre - radius; z < centre + radius; z++) {
					squareDistance = (x-centre)*(x-centre) + (y-centre) * (y-centre) + (z-centre) * (z-centre);
					if(squareDistance <= radius) w.setBlock(x, y, z, Blocks.bedrock);

				}

 

And it's still not making any sort of generation, even if i remove the 'if' statment

Former developer for DivineRPG, Pixelmon and now the maker of Essence of the Gods

Link to comment
Share on other sites

Wow, i derped really hard ahhaha....

 

So now im using this:

 

int radius = 8;
		int centre = radius / 2, squareDistance = 0;
		int x1, y1, z1;
		for(x1 = centre - radius; x1 < centre + radius; x1++)
			for(y1 = centre - radius; y1 < centre + radius; y1++)
				for(z1 = centre - radius; z1 < centre + radius; z1++) {
					squareDistance = (x-centre) * (x-centre) + (y-centre) * (y-centre) + (z-centre) * (z-centre);
					/*if(squareDistance <= (radius) * (radius))*/ w.setBlock(x + x1, y + y1, z + z1, Blocks.bedrock);
				}

 

And its generating a big square

Former developer for DivineRPG, Pixelmon and now the maker of Essence of the Gods

Link to comment
Share on other sites

  • 7 years later...

If anyone needs a working one for 1.18:

int radius = 9;
int centre = radius / 2, squareDistance;
int x1, y1, z1;

for(x1 = centre - radius; x1 < centre + radius; x1++){
	for(y1 = centre - radius; y1 < centre + radius; y1++){
		for(z1 = centre - radius; z1 < centre + radius; z1++) {
			squareDistance = (x1 -centre) * (x1 -centre) + (y1-centre) * (y1-centre) + (z1-centre) * (z1-centre);
			if(squareDistance <= (radius) * (radius))
				context.level().setBlock(new BlockPos(x + x1, y + y1, z + z1), Blocks.BEDROCK.defaultBlockState(), 11);
		}
	}
}

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.