From 359b8abfe38a049e2e7e2c0eccda1b2abbfd29f9 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 7 Jan 2014 01:44:28 +0100 Subject: [PATCH] ADD: CylinderSelection for worldguard to be able to create regions MOD: moved polygonize method of CylinderRegion to RegionUtil so it can be reused later on --- .../worldedit/bukkit/WorldEditPlugin.java | 4 ++ .../bukkit/selections/CylinderSelection.java | 61 +++++++++++++++++++ .../worldedit/regions/CylinderRegion.java | 20 +----- .../com/sk89q/worldedit/util/RegionUtil.java | 45 ++++++++++++++ 4 files changed, 113 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/sk89q/worldedit/bukkit/selections/CylinderSelection.java create mode 100644 src/main/java/com/sk89q/worldedit/util/RegionUtil.java diff --git a/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index eaba0e2af..203cb351e 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -47,9 +47,11 @@ import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditOperation; import com.sk89q.worldedit.bags.BlockBag; import com.sk89q.worldedit.bukkit.selections.CuboidSelection; +import com.sk89q.worldedit.bukkit.selections.CylinderSelection; import com.sk89q.worldedit.bukkit.selections.Polygonal2DSelection; import com.sk89q.worldedit.bukkit.selections.Selection; import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.CylinderRegion; import com.sk89q.worldedit.regions.Polygonal2DRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.RegionSelector; @@ -397,6 +399,8 @@ public class WorldEditPlugin extends JavaPlugin { return new CuboidSelection(world, selector, (CuboidRegion) region); } else if (region instanceof Polygonal2DRegion) { return new Polygonal2DSelection(world, selector, (Polygonal2DRegion) region); + } else if (region instanceof CylinderRegion) { + return new CylinderSelection(world, selector, (CylinderRegion) region); } else { return null; } diff --git a/src/main/java/com/sk89q/worldedit/bukkit/selections/CylinderSelection.java b/src/main/java/com/sk89q/worldedit/bukkit/selections/CylinderSelection.java new file mode 100644 index 000000000..ac75f20b1 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/bukkit/selections/CylinderSelection.java @@ -0,0 +1,61 @@ +package com.sk89q.worldedit.bukkit.selections; + +import org.bukkit.World; + +import com.sk89q.worldedit.BlockVector2D; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.bukkit.BukkitUtil; +import com.sk89q.worldedit.regions.CylinderRegion; +import com.sk89q.worldedit.regions.CylinderRegionSelector; +import com.sk89q.worldedit.regions.RegionSelector; + +/** + * A selection representing a {@link CylinderRegion} + */ +public class CylinderSelection extends RegionSelection { + + private CylinderRegion cylRegion; + + public CylinderSelection(World world, RegionSelector selector, CylinderRegion region) { + super(world, selector, region); + this.cylRegion = region; + } + + public CylinderSelection(World world, BlockVector2D center, BlockVector2D radius, int minY, int maxY) { + super(world); + LocalWorld lWorld = BukkitUtil.getLocalWorld(world); + + // Validate input + minY = Math.min(Math.max(0, minY), world.getMaxHeight()); + maxY = Math.min(Math.max(0, maxY), world.getMaxHeight()); + + // Create and set up new selector + CylinderRegionSelector sel = new CylinderRegionSelector(lWorld, center, radius, minY, maxY); + + // set up selection + cylRegion = sel.getIncompleteRegion(); + + // set up RegionSelection + setRegionSelector(sel); + setRegion(cylRegion); + } + + /** + * Returns the center vector of the cylinder + * + * @return the center + */ + public BlockVector2D getCenter() { + return cylRegion.getCenter().toVector2D().toBlockVector2D(); + } + + /** + * Returns the radius vector of the cylinder + * + * @return the radius + */ + public BlockVector2D getRadius() { + return cylRegion.getRadius().toBlockVector2D(); + } + +} diff --git a/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java b/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java index 998c998db..b2fa41c32 100644 --- a/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java +++ b/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java @@ -22,11 +22,13 @@ package com.sk89q.worldedit.regions; import java.util.ArrayList; import java.util.Iterator; import java.util.List; + import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.util.RegionUtil; /** * Represents a cylindrical region. @@ -366,22 +368,6 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { @Override public List polygonize(int maxPoints) { - final Vector2D radius = getRadius(); - int nPoints = (int) Math.ceil(Math.PI*radius.length()); - - // These strange semantics for maxPoints are copied from the selectSecondary method. - if (maxPoints >= 0 && nPoints >= maxPoints) { - nPoints = maxPoints - 1; - } - - final List points = new ArrayList(nPoints); - for (int i = 0; i < nPoints; ++i) { - double angle = i * (2.0 * Math.PI) / nPoints; - final Vector2D pos = new Vector2D(Math.cos(angle), Math.sin(angle)); - final BlockVector2D blockVector2D = pos.multiply(radius).add(center).toBlockVector2D(); - points.add(blockVector2D); - } - - return points; + return RegionUtil.polygonizeCylinder(center, radius, maxPoints); } } diff --git a/src/main/java/com/sk89q/worldedit/util/RegionUtil.java b/src/main/java/com/sk89q/worldedit/util/RegionUtil.java new file mode 100644 index 000000000..44eae2aa2 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/util/RegionUtil.java @@ -0,0 +1,45 @@ +package com.sk89q.worldedit.util; + +import java.util.ArrayList; +import java.util.List; + +import com.sk89q.worldedit.BlockVector2D; +import com.sk89q.worldedit.Vector2D; + +/** + * Helper method for anything related to region calculations. + */ +public class RegionUtil { + + private RegionUtil() { + + } + + /** + * Calculates the polygon shape of a cylinder which can then be used for e.g. intersection detection. + * + * @param center the center point of the cylinder + * @param radius the radius of the cylinder + * @param maxPoints max points to be used for the calculation + * @return a list of {@link BlockVector2D} which resemble the shape as a polygon + */ + public static List polygonizeCylinder(Vector2D center, Vector2D radius, int maxPoints) { + int nPoints = (int) Math.ceil(Math.PI*radius.length()); + + // These strange semantics for maxPoints are copied from the selectSecondary method. + if (maxPoints >= 0 && nPoints >= maxPoints) { + nPoints = maxPoints - 1; + } + + final List points = new ArrayList(nPoints); + for (int i = 0; i < nPoints; ++i) { + double angle = i * (2.0 * Math.PI) / nPoints; + final Vector2D pos = new Vector2D(Math.cos(angle), Math.sin(angle)); + final BlockVector2D blockVector2D = pos.multiply(radius).add(center).toBlockVector2D(); + points.add(blockVector2D); + } + + return points; + } + +}