001/*
002 * This file is part of Baritone.
003 *
004 * Baritone is free software: you can redistribute it and/or modify
005 * it under the terms of the GNU Lesser General Public License as published by
006 * the Free Software Foundation, either version 3 of the License, or
007 * (at your option) any later version.
008 *
009 * Baritone is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012 * GNU Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public License
015 * along with Baritone.  If not, see <https://www.gnu.org/licenses/>.
016 */
017
018package baritone.api.schematic.mask.shape;
019
020import baritone.api.schematic.mask.AbstractMask;
021import baritone.api.schematic.mask.StaticMask;
022
023/**
024 * @author Brady
025 */
026public final class SphereMask extends AbstractMask implements StaticMask {
027
028    private final double centerX;
029    private final double centerY;
030    private final double centerZ;
031    private final double radiusSqX;
032    private final double radiusSqY;
033    private final double radiusSqZ;
034    private final boolean filled;
035
036    public SphereMask(int widthX, int heightY, int lengthZ, boolean filled) {
037        super(widthX, heightY, lengthZ);
038        this.centerX = widthX / 2.0;
039        this.centerY = heightY / 2.0;
040        this.centerZ = lengthZ / 2.0;
041        this.radiusSqX = this.centerX * this.centerX;
042        this.radiusSqY = this.centerY * this.centerY;
043        this.radiusSqZ = this.centerZ * this.centerZ;
044        this.filled = filled;
045    }
046
047    @Override
048    public boolean partOfMask(int x, int y, int z) {
049        double dx = Math.abs((x + 0.5) - this.centerX);
050        double dy = Math.abs((y + 0.5) - this.centerY);
051        double dz = Math.abs((z + 0.5) - this.centerZ);
052        if (this.outside(dx, dy, dz)) {
053            return false;
054        }
055        return this.filled
056                || this.outside(dx + 1, dy, dz)
057                || this.outside(dx, dy + 1, dz)
058                || this.outside(dx, dy, dz + 1);
059    }
060
061    private boolean outside(double dx, double dy, double dz) {
062        return dx * dx / this.radiusSqX + dy * dy / this.radiusSqY + dz * dz / this.radiusSqZ > 1;
063    }
064}