• Hey! Register here to create your account, engage with the community, and talk about what is new!

Performing an action for every block inside a sphere

Prox

Moderator
Moderator
Joined
Sep 9, 2020
Messages
384
Reaction score
31
"Repeat on sphere exists!"
. . . and it sucks. Repeat on sphere is no good for doing something inside a sphere. Repeat on sphere does things for points on the surface of a sphere. What you want is probably for every block inside the sphere. There are multiple ways you could use repeat on sphere to do everything inside a sphere, but it's CPU intensive and overall not great. So, here's a fix.

To introduce this, here's a typed equivalent of the final code. The rest of this will explain what this means.

Code:
// r = radius, center = the center of the sphere.
SETVAR::AlignLoc(center, center) // center, please.
SETVAR::AbsoluteValue(r, r)
SETVAR::ShiftAllAxes(pos1, center, r, r, r)
nr = r * -1 // negative radius
SETVAR::ShiftAllAxes(pos2, center, nr, nr, nr)
REPEAT::OnGrid(cur, pos1, pos2) {
  SETVAR::AlignLoc(cur, cur) // same as the first align
  SETVAR::GetDistance(d, center, cur)
  if (d <= r) {
    // Your code. Use cur for locations, but do not modify cur.
  }
}

Now let's break this down. I've formatted blocks mostly as BLOCK::ACTION, with the exception of an if statement.
We have two variables, the radius of the sphere and the center of the sphere.
  1. Align the center of the sphere to the center of the block. This is just to make sure nothing weird happens, like a sphere with half of it being shifted in a certain direction.
  2. Set radius to its absolute value. This is also to make sure that our radius is definitely positive so that nothing bad happens.
  3. Set Location A to the center of our sphere, shifted by the radius on all axes. We're doing this because we're using repeat on grid to make this nice and neat
  4. Set a variable to the negative version of radius. This is to make getting the second location for repeat on grid much easier.
  5. Set Location B to the center of our sphere, shifted by the negative radius on all axes. This is self explanatory at this point.
  6. Repeat on a grid between Location A and Location B. Set the current location to cur. Self explanatory
    1. Now we're inside the repeat.
    2. Align cur to the center of the block. Again, we don't want to take any chances.
    3. Set d to the distance between cur and the center. It's if statement time.
    4. Check if d is less than or equal to r. If so, you're inside the sphere.
      1. Now we're inside the if statement. Do whatever you want here! Just don't modify cur if you plan on using it more than once.
  7. All done! If you want, you can put a CONTROL::WAIT in the repeat for CPU reasons, but that might cause problems depending on sphere size.
Where are the picture examples?
I currently can't be bothered to provide any since this is pretty self-explanatory in itself. If someone who understands wants to, feel free to send some screenshots.

This idea was thanks to @PrinceWasTaken/jim22 not being an idiot and thinking about actually using get distance, and @stinkey being able to understand what his super-vague message meant. Thanks, you two.
 

stinkey

Forum adept
Joined
Sep 8, 2020
Messages
225
Reaction score
74
recursion is also cool but df does not support function params which is 🤬 and thus recursion is 🤬
 
Top Bottom