# Solved Getting the roof of two locations

Discussion in 'Spigot Plugin Development' started by PCPSells, Jan 28, 2020.

Thread Status:
Not open for further replies.
1. ### PCPSells

I'm trying to get the "roof" of two locations. Basically the top line of two set locations.

Current code:
Code (Java):
public static Set<Location> getRoof(Location loc1, Location loc2) {
Set<Location> blocks = new HashSet<>();
int x1 = loc1.getBlockX();
int y1 = loc1.getBlockY();
int z1 = loc1.getBlockZ();
int x2 = loc2.getBlockX();
int z2 = loc2.getBlockZ();
World w = loc1.getWorld();
for (int x = x1; x <= x2; x++) {
for (int z = z1; z <= z2; z++) {
blocks.add(new Location(w, x, y1, z));
}
}
return blocks;
}
The issue with that is it doesn't work unless the loc1 is like the top left block (south)
and location two is like the bottom right (north), specifically.

So to grab the other possibilities, do I need to loop it again and check the opposite of that math or something?
Me confuzed :<

2. ### JonasArgent

As in the highest block?
Code (Java):
w.getHighestBlockAt(loc)

3. ### PCPSells

No. The roof. Like, the entire roof. The entire row of blocks of two locations.

4. ### JonasArgent

Oh, between the two locations?

For that I'd loop through the blocks(with or without getHighestBlockAt) from x to y and store them in an array.

5. ### Schottky

The „roof“ is very general, can you narrow it down?
What you have described are two lines in 3D-Space that start a two separate locations and go to a common location. However, this lacks information; more precise, this common Location is not given. It could be the middle-point between these two lines that is scaled by an arbitrary number in z-direction. It could, however, also be any point (x,y,z), where y is greater than or equal to the highest starting point y, and the projection of the point to the x-z-axis is on the line connecting the two start locations.

All I‘m saying is that your problem yields an infinite amount of solutions, without any constraints.

6. ### PCPSells

...with two known locations... grab the roof.
I don't know how to make that sound anymore... like English.

No roof: With a roof: 7. ### Schottky

In that case you have the official allowance to call me an idiot. I thought you meant a sloping roof. In that case, you simply compute the smaller values for x and z and iterate towards the bigger values.

8. ### PCPSells

Okay, so I tried that.
Code:

Code (Java):
ArrayList<Location> blocks = new ArrayList<>();
World w = loc1.getWorld();
int y = loc1.getBlockY();
if (loc1.getBlockX() <= loc2.getBlockX()) {
for (int x = loc1.getBlockX(); x <= loc2.getBlockX(); x++) {
for (int z = loc1.getBlockZ(); z >= loc2.getBlockZ(); z--) {
blocks.add(new Location(w, x, y, z));
}
}
} else {
for (int x = loc2.getBlockX(); x <= loc1.getBlockX(); x++) {
for (int z = loc2.getBlockZ(); z >= loc1.getBlockZ(); z--) {
blocks.add(new Location(w, x, y, z));
}
}
}
but for certain directions of my selections, it doesn't work.
It seems to not work when going towards positive Z and positive X.

9. ### Schottky

Here's what I mean:
Code (Java):
Location start = ...;
Location end = ...;
int xStart = Math.min(start.getBlockX(), end.getBlockX());
int xEnd = Math.max(start.getBlockX(), end.getBlockX());
int zStart = Math.min(start.getBlockZ(), end.getBlockZ());
int zEnd = Math.max(start.getBlockX(), end.getBlockX());

for (int x = xStart; x <= xEnd; x++) {
for (int z = zStart; z < zEnd; z++) {
// set block
}
}
You can replace that ugly min-max with more suitable methods.

• Informative x 1
10. ### PCPSells

Awesome, thank you!
Now, I know this may be annoying and honestly probly stupid of me to ask...
but how would I go about getting the floor of two known locations?

#10
Last edited: Jan 28, 2020
11. ### Schottky

That is because you blindly copied my code Code (Java):
int zEnd = Math.max(loc1.getBlockX(), loc2.getBlockX());
needs to be changed to
Code (Java):
int zEnd = Math.max(loc1.getBlockZ(), loc2.getBlockZ());
The same can be done for y btw, so you don't have to do that if/else:
Code (Java):
int y = Math.max(loc1.getBlockY(), loc2.getBlockY());

• Informative x 1
12. ### PCPSells

I noticed and fixed My bad.
(I updated my previous message)

13. ### Schottky

The floor is just the smaller y-values of the two locations (the rest stays the same). So, instead of using
Code (Java):
int y = Math.max(loc1.getBlockY(), loc2.getBlockY());
use:
Code (Java):
int y = Math.min(loc1.getBlockY(), loc2.getBlockY());

• Informative x 1
14. ### PCPSells

Ah okay, I figured as much, but didn't want to sound dumb... even though I already have.
Thank you sir! Thread Status:
Not open for further replies.