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. 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. As in the highest block?
    Code (Java):
    w.getHighestBlockAt(loc)
     
  3. No. The roof. Like, the entire roof. The entire row of blocks of two locations.
     
  4. 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. 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. ...with two known locations... grab the roof.
    I don't know how to make that sound anymore... like English.

    No roof:
    [​IMG]

    With a roof:
    [​IMG]
     
  7. 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. 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. 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 Informative x 1
  10. 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 PCPSells, Jan 28, 2020
    Last edited: Jan 28, 2020
  11. That is because you blindly copied my code :p

    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 Informative x 1
  12. I noticed and fixed :p
    My bad.
    (I updated my previous message)
     
  13. 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 Informative x 1
  14. 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.