diff --git a/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java b/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java new file mode 100644 index 000000000..04cb256aa --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java @@ -0,0 +1,148 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.regions; + +import com.google.common.collect.Iterators; +import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.Vector; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * An intersection of several other regions. Any location that is contained in one + * of the child regions is considered as contained by this region. + *

+ * {@link #iterator()} returns a special iterator that will iterate through + * the iterators of each region in an undefined sequence. Some positions may + * be repeated if the position is contained in more than one region, but this cannot + * be guaranteed to occur. + */ +public class RegionIntersection extends AbstractRegion { + + private final List regions = new ArrayList(); + + /** + * Create a new instance with the included list of regions. + * + * @param regions a list of regions, which is copied + */ + public RegionIntersection(List regions) { + this(null, regions); + } + + /** + * Create a new instance with the included list of regions. + * + * @param regions a list of regions, which is copied + */ + public RegionIntersection(Region... regions) { + this(null, regions); + } + + /** + * Create a new instance with the included list of regions. + * + * @param world the world + * @param regions a list of regions, which is copied + */ + public RegionIntersection(LocalWorld world, List regions) { + super(world); + checkNotNull(regions); + checkArgument(regions.size() > 0, "empty region list is not supported"); + for (Region region : regions) { + this.regions.add(region); + } + } + + /** + * Create a new instance with the included list of regions. + * + * @param world the world + * @param regions an array of regions, which is copied + */ + public RegionIntersection(LocalWorld world, Region... regions) { + super(world); + checkNotNull(regions); + checkArgument(regions.length > 0, "empty region list is not supported"); + for (Region region : regions) { + this.regions.add(region); + } + } + + @Override + public Vector getMinimumPoint() { + Vector minimum = regions.get(0).getMinimumPoint(); + for (int i = 1; i < regions.size(); i++) { + minimum = Vector.getMinimum(regions.get(i).getMinimumPoint(), minimum); + } + return minimum; + } + + @Override + public Vector getMaximumPoint() { + Vector maximum = regions.get(0).getMaximumPoint(); + for (int i = 1; i < regions.size(); i++) { + maximum = Vector.getMaximum(regions.get(i).getMaximumPoint(), maximum); + } + return maximum; + } + + @Override + public void expand(Vector... changes) throws RegionOperationException { + checkNotNull(changes); + throw new RegionOperationException("Cannot expand a region intersection"); + } + + @Override + public void contract(Vector... changes) throws RegionOperationException { + checkNotNull(changes); + throw new RegionOperationException("Cannot contract a region intersection"); + } + + @Override + public boolean contains(Vector pt) { + checkNotNull(pt); + + for (Region region : regions) { + if (region.contains(pt)) { + return true; + } + } + + return false; + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + @Override + public Iterator iterator() { + Iterator[] iterators = (Iterator[]) new Iterator[regions.size()]; + for (int i = 0; i < regions.size(); i++) { + iterators[i] = regions.get(i).iterator(); + } + return Iterators.concat(iterators); + } + +}