From 65f85d54e9402bf422f534373ee4ec802789fc22 Mon Sep 17 00:00:00 2001 From: LazyGon <26216029+LazyGon@users.noreply.github.com> Date: Fri, 23 Sep 2022 04:51:53 +0900 Subject: [PATCH 1/4] fix: fixed bug that polygon area is not rendered correctly. --- .../worldguard/DynmapWorldGuardPlugin.java | 112 ++++++++++++++---- 1 file changed, 91 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java b/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java index 74d9aad..15708b2 100644 --- a/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java +++ b/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java @@ -1,7 +1,9 @@ package org.dynmap.worldguard; +import com.sk89q.worldedit.regions.Polygonal2DRegion; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -227,7 +229,83 @@ else if((tok.length >= 2) && resid.startsWith(tok[0]) && resid.endsWith(tok[1])) m.setBoostFlag((b == null)?false:b.booleanValue()); } } - + + private static double cross(BlockVector2 p1, BlockVector2 p2) { + return p1.getX() * p2.getZ() - p1.getZ() * p2.getX(); + } + + private static double calcAreaOfPolygon(List points) { + double area = 0; + for (int i = 0; i < points.size(); i++) { + area += cross(points.get(i), points.get((i + 1) % points.size())); + } + return area / 2.0; + } + + /** + * Calc loop direction of given polygon. + * + * @param points Polygon points. + * + * @return When returns 1 it is clockwise, when returns -1 it is anticlockwise. + * Other than that, polygon is collapsed. + */ + private static int getPolygonLoop(List points) { + double area = calcAreaOfPolygon(points); + if (area > 0) { + return 1; + } else if (area < 0) { + return -1; + } else { + return 0; + } + } + + private static List expandPolygonXZByOne(List points) { + List pointsCopy = new ArrayList<>(points); + if (points.size() < 3) { + return pointsCopy; + } + + List result = new ArrayList<>(); + int loop = getPolygonLoop(points); + if (loop == 0) { + Polygonal2DRegion poly2d = new Polygonal2DRegion(null, points, 0, 0); + BlockVector2 max = poly2d.getMaximumPoint().toBlockVector2(); + BlockVector2 min = poly2d.getMinimumPoint().toBlockVector2(); + result.add(max); + result.add(max.add(1, 0)); + result.add(min.add(1, 0)); + result.add(min); + return result; + } + if (loop != 1) { + Collections.reverse(pointsCopy); + } + + for (int i = 0; i < pointsCopy.size(); i++) { + int xPrev = pointsCopy.get((i - 1 + pointsCopy.size()) % pointsCopy.size()).getX(); + int zPrev = pointsCopy.get((i - 1 + pointsCopy.size()) % pointsCopy.size()).getZ(); + int xCur = pointsCopy.get(i).getX(); + int zCur = pointsCopy.get(i).getZ(); + int xNext = pointsCopy.get((i + 1) % pointsCopy.size()).getX(); + int zNext = pointsCopy.get((i + 1) % pointsCopy.size()).getZ(); + + int xCurNew = xCur; + int zCurNew = zCur; + + if (zPrev < zCur || zCur < zNext) { + xCurNew++; + } + if (xCur < xPrev || xNext < xCur) { + zCurNew++; + } + + result.add(BlockVector2.at(xCurNew, zCurNew)); + } + return result; + } + /* Handle specific region */ private void handleRegion(World world, ProtectedRegion region, Map newmap) { String name = region.getId(); @@ -243,28 +321,20 @@ private void handleRegion(World world, ProtectedRegion region, Map points = ppr.getPoints(); - x = new double[points.size()]; - z = new double[points.size()]; - for(int i = 0; i < points.size(); i++) { - BlockVector2 pt = points.get(i); - x[i] = pt.getX(); z[i] = pt.getZ(); - } - } - else { /* Unsupported type */ + if(tn != RegionType.CUBOID && tn != RegionType.POLYGON) { + /* Unsupported type */ return; } + + /* Make outline */ + List points = expandPolygonXZByOne(region.getPoints()); + x = new double[4]; + z = new double[4]; + for (int i = 0; i < points.size(); i++) { + x[i] = points.get(i).getX(); + z[i] = points.get(i).getZ(); + } + String markerid = world.getName() + "_" + id; AreaMarker m = resareas.remove(markerid); /* Existing area? */ if(m == null) { From 0204208b40895f5cd059cddd264ea3e69e9a1275 Mon Sep 17 00:00:00 2001 From: LazyGon <26216029+LazyGon@users.noreply.github.com> Date: Fri, 23 Sep 2022 05:18:13 +0900 Subject: [PATCH 2/4] fix: IndexOutOfBoundException --- .../java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java b/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java index 15708b2..207467e 100644 --- a/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java +++ b/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java @@ -328,8 +328,8 @@ private void handleRegion(World world, ProtectedRegion region, Map points = expandPolygonXZByOne(region.getPoints()); - x = new double[4]; - z = new double[4]; + x = new double[points.size()]; + z = new double[points.size()]; for (int i = 0; i < points.size(); i++) { x[i] = points.get(i).getX(); z[i] = points.get(i).getZ(); From 4563c2b92fe5a2604de11d7f2966ead6348b3a72 Mon Sep 17 00:00:00 2001 From: LazyGon <26216029+LazyGon@users.noreply.github.com> Date: Sat, 1 Oct 2022 09:41:09 +0900 Subject: [PATCH 3/4] fix bug that collapsed polygon claim is not rendered collect. --- .../dynmap/worldguard/DynmapWorldGuardPlugin.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java b/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java index 207467e..1d0b901 100644 --- a/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java +++ b/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java @@ -273,10 +273,17 @@ private static List expandPolygonXZByOne(List points Polygonal2DRegion poly2d = new Polygonal2DRegion(null, points, 0, 0); BlockVector2 max = poly2d.getMaximumPoint().toBlockVector2(); BlockVector2 min = poly2d.getMinimumPoint().toBlockVector2(); - result.add(max); - result.add(max.add(1, 0)); - result.add(min.add(1, 0)); - result.add(min); + if (min.getBlockX() == max.getBlockX()) { + result.add(min); + result.add(max.add(0, 1)); + result.add(max.add(1, 1)); + result.add(min.add(1, 0)); + } else { + result.add(min); + result.add(max.add(1, 0)); + result.add(max.add(1, 1)); + result.add(min.add(0, 1)); + } return result; } if (loop != 1) { From 670f13fe13fb4ffa419bca7519480c2db70d48b3 Mon Sep 17 00:00:00 2001 From: LazyGon <26216029+LazyGon@users.noreply.github.com> Date: Thu, 6 Oct 2022 12:11:09 +0900 Subject: [PATCH 4/4] fix: rendering of acicular part of polygon --- .../worldguard/DynmapWorldGuardPlugin.java | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java b/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java index 1d0b901..f8fdc50 100644 --- a/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java +++ b/src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java @@ -290,21 +290,36 @@ private static List expandPolygonXZByOne(List points Collections.reverse(pointsCopy); } + List pointAdded = new ArrayList<>(); for (int i = 0; i < pointsCopy.size(); i++) { - int xPrev = pointsCopy.get((i - 1 + pointsCopy.size()) % pointsCopy.size()).getX(); - int zPrev = pointsCopy.get((i - 1 + pointsCopy.size()) % pointsCopy.size()).getZ(); - int xCur = pointsCopy.get(i).getX(); - int zCur = pointsCopy.get(i).getZ(); - int xNext = pointsCopy.get((i + 1) % pointsCopy.size()).getX(); - int zNext = pointsCopy.get((i + 1) % pointsCopy.size()).getZ(); + BlockVector2 prev = pointsCopy.get((i - 1 + pointsCopy.size()) % pointsCopy.size()); + BlockVector2 cur = pointsCopy.get(i); + BlockVector2 next = pointsCopy.get((i + 1) % pointsCopy.size()); + pointAdded.add(cur); + if (cross(cur.subtract(prev), next.subtract(cur)) == 0 && cur.subtract(prev).dot(next.subtract(cur)) < 0) { + pointAdded.add(cur); + } + } + pointsCopy = pointAdded; + + for (int i = 0; i < pointsCopy.size(); i++) { + BlockVector2 prev = pointsCopy.get((i - 1 + pointsCopy.size()) % pointsCopy.size()); + BlockVector2 cur = pointsCopy.get(i); + BlockVector2 next = pointsCopy.get((i + 1) % pointsCopy.size()); + int xPrev = prev.getX(); + int zPrev = prev.getZ(); + int xCur = cur.getX(); + int zCur = cur.getZ(); + int xNext = next.getX(); + int zNext = next.getZ(); int xCurNew = xCur; int zCurNew = zCur; - if (zPrev < zCur || zCur < zNext) { + if (zPrev < zCur || zCur < zNext || cur.equals(next) && xPrev < xCur || prev.equals(cur) && xNext < xCur) { xCurNew++; } - if (xCur < xPrev || xNext < xCur) { + if (xCur < xPrev || xNext < xCur || cur.equals(next) && zPrev < zCur || prev.equals(cur) && zNext < zCur) { zCurNew++; }