Solved Intersecting Cuboids

Discussion in 'Plugin Development' started by CorrieKay, Dec 5, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    CorrieKay

    If you have two cuboids with their opposite vectors (such as with world edits selection/regions) how would you go about discerning if one cuboid is intersecting another cuboid? I know it must be a fairly simple solution... right?
     
  2. This is what I use:
    Code:
        public boolean intersects(CuboidRegion region) {
            // some null and world-specific checks
     
            return !(pos1X > region.pos2X || pos1Y > region.pos2Y || pos1Z > region.pos2Z || pos2X < region.pos1X || pos2Y < region.pos1Y || pos2Z < region.pos1Z);
        }
    My class is implemented so that pos1 is always the corner with the lowest coordinates and pos2 the one with the highest. If that's not your case and you have any arbitrary two points, you have to get get the right ones with Math.min and Math.max at first.

    What it checks: As soon as the lower coordinate of any dimension is higher than the upper cordinate of the other region or vice versa, the cuboids can't intersect.
     
    CorrieKay likes this.
  3. Offline

    CorrieKay

    Alright, i think i got this, would this work?
    Code:
        private boolean intersects(CuboidSelection s1, CuboidSelection s2){
            int pos1X, pos2X, pos1Y, pos2Y, pos1Z, pos2Z;
            Location s1Min, s1Max, s2Min, s2Max;
            s1Min = s1.getMinimumPoint();
            s1Max = s1.getMaximumPoint();
            s2Min = s2.getMinimumPoint();
            s2Max = s1.getMaximumPoint();
            pos1X = s1Min.getBlockX()<s1Max.getBlockX()?s1Min.getBlockX():s1Max.getBlockX();
            pos1Y = s1Min.getBlockY()<s1Max.getBlockY()?s1Min.getBlockY():s1Max.getBlockY();
            pos1Z = s1Min.getBlockZ()<s1Max.getBlockZ()?s1Min.getBlockZ():s1Max.getBlockZ();
            pos2X = s2Min.getBlockX()>s2Max.getBlockX()?s2Min.getBlockX():s2Max.getBlockX();
            pos2Y = s2Min.getBlockY()>s2Max.getBlockY()?s2Min.getBlockY():s2Max.getBlockY();
            pos2Z = s2Min.getBlockZ()>s2Max.getBlockZ()?s2Min.getBlockZ():s2Max.getBlockZ();
            return !(pos1X > pos2X || pos1Y > pos2Y || pos1Z > pos2Z || pos2X < pos1X || pos2Y < pos1Y || pos2Z < pos1Z);
        }
    
     
  4. Looks valid.
    • You can write your conditionals more cleanly, though: Instead of "a<b ? a : b", you can simply do "Math.min(a, b)" and respectively Math.max for the maximum position.
    • Typo at "s2Max", should be s2, I guess
    • Not sure what class you are using (WorldEdit?), but "getMinimumPoint()" and "getMaximumPoint()" already suggest that they give you the corners you are looking for. If that's the case, you can completely leave out the conditions. If it's WorldEdit's API that you are using, I'm pretty sure those methods do actually do that. (there are separate ones to get the real pos1 and pos2 that the player selected).
     
  5. Offline

    CorrieKay

    Coolio, first time writing an inline if statement though, thanks for the pointers. And yeah, typo there, perils of copypasting code :p And yes, im using world edit's api. I dont think checking if the min/max are intersecting, it accounts for all possibilities though. if one of the corners not min/max is intersecting another cuboids non-min/max, it wont catch it.

    Alright, i think i got it this time, how about this?

    Code:
        private boolean intersects(CuboidSelection s1, CuboidSelection s2){
            int pos1X, pos2X, pos1Y, pos2Y, pos1Z, pos2Z;
            Location s1Min, s1Max, s2Min, s2Max;
            s1Min = s1.getMinimumPoint();
            s1Max = s1.getMaximumPoint();
            s2Min = s2.getMinimumPoint();
            s2Max = s2.getMaximumPoint();
            pos1X = Math.min(s1Min.getBlockX(),s1Max.getBlockX());
            pos1Y = Math.min(s1Min.getBlockY(),s1Max.getBlockY());
            pos1Z = Math.min(s1Min.getBlockZ(),s1Max.getBlockZ());
            pos2X = Math.max(s2Min.getBlockX(),s2Max.getBlockX());
            pos2Y = Math.max(s2Min.getBlockY(),s2Max.getBlockY());
            pos2Z = Math.max(s2Min.getBlockZ(),s2Max.getBlockZ());
            return !(pos1X > pos2X || pos1Y > pos2Y || pos1Z > pos2Z || pos2X < pos1X || pos2Y < pos1Y || pos2Z < pos1Z);
        }
    
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 30, 2016
  6. Offline

    Technius

    EDIT: Scrap that, I didn't fully read the code


    If you want to see it anyways (open)

    That code would work, but I've thought about it a bit.

    If your cuboids look like any of these:
    cuboidexample1.png

    Then it would work because there is at least one point contained in one of those.

    But what about this?
    cuboidexample2.png

    Neither of the two cuboids contain any of the corners in each other. A solution would be to get all the blocks in the "frame" of the first one and then see if the second one contains any of those blocks. I don't have the time to put code here like that at the moment, so I'll leave that up to you. :)
     
  7. Offline

    CorrieKay

    Im having an issue.. For some reason it is saying its always intersecting another cuboid, wether or not it actually is, isnt, or even if it is the same exact cuboid :\
     
Thread Status:
Not open for further replies.

Share This Page