getArea() and Polygonal2DRegion - don't return real value.
LadyCailinBot opened this issue ยท 8 comments
WORLDEDIT-3096 - Reported by BukkitSmerf
Every Polygonal2DRegion returns other sizes than should, even rectangles:
Example code:
Polygonal2DRegion polReg = new Polygonal2DRegion();
polReg.addPoint(new BlockVector2D(1, 1));
polReg.addPoint(new BlockVector2D(1, 10));
polReg.addPoint(new BlockVector2D(10, 10));
polReg.addPoint(new BlockVector2D(10, 1));
// 10x10 = 100
sender.sendMessage(Integer.toString(polReg.getArea()));
// send 89 (9x9) instead of 100
I need that to block creating too big regions/selections.
Comment by wizjany
duplicate
edit: spoke to soon, apparently WE is just as broken as WG?
however your code is using the wrong kind of region - WG regions and WE regions are not interchangeable
Comment by BukkitSmerf
I only need size, but WG don't provide any options in ProtectedPolygonalRegion, so I used WE by java new Polygonal2DRegion(null, protectedPolygonalRegion.getPoints(), 64, 64);
;/ PS: any idea how to fix this, and calculate size without WE?
Comment by sk89q
Well, you'll need a better algorithm than the one that WE uses, which is apparently broken.
I don't have a better one off my head, otherwise WE would already be using it. You can try searching the web. Be careful though: most implementations are not for discrete points (blocks).
Comment by BukkitSmerf
hyym... So problem is in Minecraft blocks?, in normal math, if you have point x = 1 and x = 10 then you have 9 units, but in minecraft - 10 units? ;/ But I have no idea how to fix that...
But maybe this code can be used:
public static int getArea(Polygonal2DRegion region)
{
Vector maxP = region.getMaximumPoint();
Vector minP = region.getMinimumPoint();
int minY = minP.getBlockY();
int maxY = maxP.getBlockY();
int y = (minY + maxY) / 2;
int size = 0;
for (int x = minP.getBlockX(); x <= maxP.getBlockX(); x++)
{
for (int z = minP.getBlockZ(); z <= maxP.getBlockY(); z++)
{
if (region.contains(new BlockVector(x, y, z)))
{
size++;
}
}
}
return size * ((maxY - minY) + 1);
}```
Tested on region with 102 points and 101x101 size [very big "spiral"], and works good with time between 15-8 ms.
Maybe not great, but seems to work.
Comment by sk89q
That does work, but yeah, as you said, it's not ideal.
Unfortunately, I have not yet studied computational geometry.
Comment by BukkitSmerf
Me too :/ But i think that code will be better than old - return good size, but in longer time. (1000 x 1000 - 80 ms ;/) And... only //size command is using this?
I looking for any code for my plugin so I ask question here: http://stackoverflow.com/questions/23136512/area-of-polygon
Maybe one of comments will be helpful for you. (I'm too weak in math to fully understand all this algorithms))
Comment by Dark_Arc
@BukkitSmerf feel free to test this algorithm, I never got around to finishing the testing of it: https://github.com/sk89q/worldguard/blob/f5a3d6300453b0448cddd6f679efcfc7eb305ddb/src/main/java/com/sk89q/worldguard/protection/regions/ProtectedPolygonalRegion.java#L160