dfhack icon indicating copy to clipboard operation
dfhack copied to clipboard

Cuboid struct/class for df::coord bounds

Open Bumber64 opened this issue 1 year ago • 0 comments

Testing if a df::coord is inside a given box is an issue that comes up when dealing with map positions. There doesn't seem to be anything handy in the DFHack library, so every tool has to implement its own logic.

Not sure where the struct should be defined. MiscUtils?

I created an example while working on an improved plugins/plants.cpp:

struct cuboid
{
    int16_t x_min = -1;
    int16_t x_max = -1;
    int16_t y_min = -1;
    int16_t y_max = -1;
    int16_t z_min = -1;
    int16_t z_max = -1;

    bool isValid() const
    {   // False if any bound is < 0
        return x_min >= 0 && x_max >= 0 &&
            y_min >= 0 && y_max >= 0 &&
            z_min >= 0 && z_max >= 0;
    }

    bool addPos(int16_t x, int16_t y, int16_t z)
    {   // Expand cuboid to include point. Return true if bounds changed
        if (x < 0 || y < 0 || z < 0 || (isValid() && testPos(x, y, z)))
            return false;

        x_min = (x_min < 0 || x < x_min) ? x : x_min;
        x_max = (x_max < 0 || x > x_max) ? x : x_max;

        y_min = (y_min < 0 || y < y_min) ? y : y_min;
        y_max = (y_max < 0 || y > y_max) ? y : y_max;

        z_min = (z_min < 0 || z < z_min) ? z : z_min;
        z_max = (z_max < 0 || z > z_max) ? z : z_max;

        return true;
    }
    inline bool addPos(df::coord pos) { return addPos(pos.x, pos.y, pos.z); }

    bool testPos(int16_t x, int16_t y, int16_t z) const
    {   // Return true if point inside cuboid. Make sure cuboid is valid first!
        return x >= x_min && x <= x_max &&
            y >= y_min && y <= y_max &&
            z >= z_min && z <= z_max;
    }
    inline bool testPos(df::coord pos) const { return testPos(pos.x, pos.y, pos.z); }
};

This could probably be refined. (I don't know if there's a use-case for supporting negative values, but this implementation doesn't.)

Some existing plugins that could make use of this include plugins/blueprint.cpp and plugins/regrass.cpp. gui/teleport.lua could probably make use of this if Lua doesn't make that a pain.

Bumber64 avatar May 16 '24 12:05 Bumber64