Search in sources :

Example 1 with Vector2

use of com.sk89q.worldedit.math.Vector2 in project ProtectionStones by espidev.

the class RegionTraverse method traverseRegionEdge.

// can't use recursion because stack overflow
// doesn't do so well with 1 block wide segments jutting out
public static void traverseRegionEdge(HashSet<BlockVector2> points, List<ProtectedRegion> regions, Consumer<TraverseReturn> run) {
    int pointID = 0;
    while (!points.isEmpty()) {
        BlockVector2 start = points.iterator().next();
        TraverseData td = new TraverseData(start, null, true);
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ algorithm starts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        boolean cont = true;
        while (cont) {
            cont = false;
            BlockVector2 v = td.v, previous = td.previous;
            if (!td.first && v.equals(start))
                break;
            int exposedEdges = 0;
            List<BlockVector2> insideVertex = new ArrayList<>();
            for (Vector2 dir : DIRECTIONS) {
                BlockVector2 test = BlockVector2.at(v.getX() + dir.getX(), v.getZ() + dir.getZ());
                if (!isInRegion(test, regions)) {
                    exposedEdges++;
                } else {
                    insideVertex.add(test);
                }
            }
            // remove current point if it exists
            points.remove(v);
            switch(exposedEdges) {
                case // normal edge
                1:
                    // run consumer
                    run.accept(new TraverseReturn(v, false, pointID, exposedEdges));
                    if (previous == null) {
                        // if this is the first node we need to determine a direction to go to (that isn't into the polygon, but is on edge)
                        if (insideVertex.get(0).getX() == insideVertex.get(1).getZ() || insideVertex.get(0).getZ() == insideVertex.get(1).getZ() || insideVertex.get(0).getX() == insideVertex.get(2).getZ() || insideVertex.get(0).getZ() == insideVertex.get(2).getZ()) {
                            previous = insideVertex.get(0);
                        } else {
                            previous = insideVertex.get(1);
                        }
                    }
                    td = new TraverseData(BlockVector2.at(v.getX() + (v.getX() - previous.getX()), v.getZ() + (v.getZ() - previous.getZ())), v, false);
                    cont = true;
                    break;
                case // convex vertex
                2:
                    // possibly also 1 block wide segment with 2 edges opposite, but we'll ignore that
                    // run consumer
                    run.accept(new TraverseReturn(v, true, pointID, exposedEdges));
                    if (insideVertex.get(0).equals(previous)) {
                        td = new TraverseData(insideVertex.get(1), v, false);
                        cont = true;
                    } else {
                        td = new TraverseData(insideVertex.get(0), v, false);
                        cont = true;
                    }
                    break;
                case // random 1x1 jutting out
                3:
                    // it's fine right now but it'd be nice if it worked
                    break;
                case // concave vertex, or point in middle of region
                0:
                    List<Vector2> cornersNotIn = new ArrayList<>();
                    for (Vector2 dir : CORNER_DIRECTIONS) {
                        BlockVector2 test = BlockVector2.at(v.getX() + dir.getX(), v.getZ() + dir.getZ());
                        if (!isInRegion(test, regions))
                            cornersNotIn.add(dir);
                    }
                    if (cornersNotIn.size() == 1) {
                        // concave vertex
                        // run consumer
                        run.accept(new TraverseReturn(v, true, pointID, exposedEdges));
                        Vector2 dir = cornersNotIn.get(0);
                        if (previous == null || previous.equals(BlockVector2.at(v.getX() + dir.getX(), v.getZ()))) {
                            td = new TraverseData(BlockVector2.at(v.getX(), v.getZ() + dir.getZ()), v, false);
                            cont = true;
                        } else {
                            td = new TraverseData(BlockVector2.at(v.getX() + dir.getX(), v.getZ()), v, false);
                            cont = true;
                        }
                    } else if (cornersNotIn.size() == 2) {
                        // 1 block diagonal perfect overlap
                        // run consumer
                        run.accept(new TraverseReturn(v, false, pointID, exposedEdges));
                        if (previous == null)
                            previous = insideVertex.get(0);
                        td = new TraverseData(BlockVector2.at(v.getX() + (v.getX() - previous.getX()), v.getZ() + (v.getZ() - previous.getZ())), v, false);
                        cont = true;
                    }
                    // ignore if in middle of region (cornersNotIn size = 0)
                    break;
            }
        }
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ algorithm ends ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        pointID++;
    }
}
Also used : BlockVector2(com.sk89q.worldedit.math.BlockVector2) Vector2(com.sk89q.worldedit.math.Vector2) ArrayList(java.util.ArrayList) BlockVector2(com.sk89q.worldedit.math.BlockVector2)

Example 2 with Vector2

use of com.sk89q.worldedit.math.Vector2 in project FastAsyncWorldEdit by IntellectualSites.

the class CylinderRegionSelector method selectSecondary.

@Override
public boolean selectSecondary(BlockVector3 position, SelectorLimits limits) {
    if (!selectedCenter) {
        return true;
    }
    final Vector2 diff = position.toVector3().subtract(region.getCenter()).toVector2();
    final Vector2 minRadius = diff.getMaximum(diff.multiply(-1.0));
    region.extendRadius(minRadius);
    region.setY(position.getBlockY());
    selectedRadius = true;
    return true;
}
Also used : BlockVector2(com.sk89q.worldedit.math.BlockVector2) Vector2(com.sk89q.worldedit.math.Vector2)

Example 3 with Vector2

use of com.sk89q.worldedit.math.Vector2 in project FastAsyncWorldEdit by IntellectualSites.

the class CylinderRegion method createRadius.

/**
 * Return a new instance with the given center and radius in the X and Z
 * axes with a Y that extends from the bottom of the extent to the top
 * of the extent.
 *
 * @param extent the extent
 * @param center the center position
 * @param radius the radius in the X and Z axes
 * @return a region
 */
public static CylinderRegion createRadius(Extent extent, BlockVector3 center, double radius) {
    checkNotNull(extent);
    checkNotNull(center);
    Vector2 radiusVec = Vector2.at(radius, radius);
    int minY = extent.getMinimumPoint().getBlockY();
    int maxY = extent.getMaximumPoint().getBlockY();
    return new CylinderRegion(center, radiusVec, minY, maxY);
}
Also used : BlockVector2(com.sk89q.worldedit.math.BlockVector2) Vector2(com.sk89q.worldedit.math.Vector2)

Example 4 with Vector2

use of com.sk89q.worldedit.math.Vector2 in project FastAsyncWorldEdit by IntellectualSites.

the class Polygons method polygonizeCylinder.

/**
 * 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 BlockVector2} which resemble the shape as a polygon
 */
public static List<BlockVector2> polygonizeCylinder(BlockVector2 center, Vector2 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<BlockVector2> points = new ArrayList<>(nPoints);
    for (int i = 0; i < nPoints; ++i) {
        double angle = i * (2.0 * Math.PI) / nPoints;
        final Vector2 pos = Vector2.at(Math.cos(angle), Math.sin(angle));
        final BlockVector2 blockVector2D = pos.multiply(radius).toBlockPoint().add(center);
        points.add(blockVector2D);
    }
    return points;
}
Also used : BlockVector2(com.sk89q.worldedit.math.BlockVector2) Vector2(com.sk89q.worldedit.math.Vector2) ArrayList(java.util.ArrayList) BlockVector2(com.sk89q.worldedit.math.BlockVector2)

Example 5 with Vector2

use of com.sk89q.worldedit.math.Vector2 in project FastAsyncWorldEdit by IntellectualSites.

the class Spline method pastePositionDirect.

/**
 * Paste structure at the provided position on the curve. The position will not be position-corrected
 * but will be passed directly to the interpolation algorithm.
 *
 * @param position The position on the curve. Must be between 0.0 and 1.0 (both inclusive)
 * @return The amount of blocks that have been changed
 * @throws MaxChangedBlocksException Thrown by WorldEdit if the limit of block changes for the {@link EditSession} has been reached
 */
public int pastePositionDirect(double position) throws MaxChangedBlocksException {
    Preconditions.checkArgument(position >= 0);
    Preconditions.checkArgument(position <= 1);
    // Calculate position from spline
    Vector3 target = interpolation.getPosition(position);
    BlockVector3 blockTarget = target.toBlockPoint();
    Vector3 offset = target.subtract(target.floor());
    // Calculate rotation from spline
    Vector3 deriv = interpolation.get1stDerivative(position);
    Vector2 deriv2D = Vector2.at(deriv.getX(), deriv.getZ()).normalize();
    double angle = Math.toDegrees(-Math.atan2(cross2D(direction, deriv2D), direction.dot(deriv2D)));
    // Wrap to 360 degrees
    angle = ((angle % 360) + 360) % 360;
    return pasteBlocks(blockTarget, offset, angle);
}
Also used : Vector2(com.sk89q.worldedit.math.Vector2) BlockVector3(com.sk89q.worldedit.math.BlockVector3) Vector3(com.sk89q.worldedit.math.Vector3) BlockVector3(com.sk89q.worldedit.math.BlockVector3)

Aggregations

Vector2 (com.sk89q.worldedit.math.Vector2)7 BlockVector2 (com.sk89q.worldedit.math.BlockVector2)6 BlockVector3 (com.sk89q.worldedit.math.BlockVector3)3 Vector3 (com.sk89q.worldedit.math.Vector3)2 ArrayList (java.util.ArrayList)2 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1