Calculating the area of a polygonal region

Discussion in 'Spigot Plugin Development' started by Quasindro, Apr 26, 2017.

  1. It's probably an easy fix but I really can't figure it out. I have a method that calculates the area of a polygon in the cartesian plane:
    Code (Java):
        private int calculateArea(List<BlockVector2D> vectors) {
            int area = 0;
            int j = vectors.size() - 1;

            for (int i = 0; i < vectors.size(); i++) {
                area += (vectors.get(j).getBlockX() + vectors.get(i).getBlockX()) * (vectors.get(j).getBlockZ() - vectors.get(i).getBlockZ());
                j = i;
            }
            return Math.abs(area / 2);
        }
    Yet it doesn't really work in Minecraft. Here's the pretty-accurate-please-i-tried-my-best picture:
    [​IMG]

    I have tried multiple ways to extend some of the variables by one but it messed it all up. I feel so stupid for not being able to fix this. It's just math after all.
     
  2. Five units can't be = six blocks otherwise your top section would be 6x6 not 6x5

    I feel like your math is probably ok but the area you are measuring is larger than the one you laid out by hand.

    If you count the minecraft blocks the area is larger than the drawing on the left. That being said 6*5 = 30 + 6*11 = 66
    66 + 30 = 96
    Exactly what it says on the screen.

    Is your method not returning 96 in mc?


    Sent from my iPhone using Tapatalk
     
  3. It returns 75.
     
  4. It looks like you're adding the x values and subtracting the z values. In minecraft x and z variables can be either positive or negative.

    The problem probably lies in the positioning of this the polygon in the world. It should only work if the x values are all positives and the z values are all negatives.

    What does your code look like where you add the vectors to the list? How are you adding the points?

    If you add two negative numbers it's negative, but if you add -5x to positive 5x you get zero which will throw your area off. You will need to account for the actual positioning of the polygon in the world. Because if part of your cords are negative and parts are positive you need to account for that.

    OR you could ignore the positioning and count the number of x blocks and z blocks so you end up with whole positive numbers and calculate your area based on the number of blocks.

    Ie loop through all the getBlockX in the vectors and increment x by one.

    Then do the same for blockZ with a z counter

    What you're left with is x = 0 to whatever the count was
    And z = 0 to whatever the z was

    Then you should be able to simply x * z



    Sent from my iPhone using Tapatalk
     
  5. Well, no, the positioning is not a problem. The area is calculated correctly, it is just measured in cartesian units instead of actual blocks that have some dimensions themselves.
    A line ranging from X=82 to X=77 on a cartesian plane would be considered 5 units long because 82-77=5. But that is not the case with Minecraft blocks because it's the blocks coordinates and all of them are counted (count the numbers ranging from 77 to 82. There are six of them, not five!). No matter where you put that plot in a world, it will always give the same result - the area of 75 units because that's how it's being measured and it's correct for a cartesian plane. I just need to modify the algorithm to account for that.

    I guess it would be possible to do it with counting blocks or whatever but I want to do it dynamically and make it as optimized as I can.
     
  6. shameless bump because page 3
     
  7. last bamp just in case, I guess I will just use this ghetto method and conceal all the results from the users for now
     
  8. Did you ever figure this out? I am having the same problem...
    I get the correct result but not from a Minecraft perspective.

    Code (Java):
        public static double calculatePolygonalArea(List<BlockVector2> points) {

            // https://www.wikihow.com/Calculate-the-Area-of-a-Polygon#Finding-the-Area-of-Irregular-Polygons

            BlockVector2[] vectors = points.toArray(new BlockVector2[0]);

            int sum = 0;
            for (int i = 0; i < vectors.length ; i++)
            {
                int xSum = 0;
                int zSum = 0;
                if (i < vectors.length - 1) {
                    xSum = vectors[i].getX() * vectors[i + 1].getZ();
                    zSum = vectors[i].getZ() * vectors[i + 1].getX();
                } else if (i == vectors.length - 1) {
                    xSum = vectors[i].getX() * vectors[0].getZ();
                    zSum = vectors[i].getZ() * vectors[0].getX();
                }
                sum += xSum - zSum;
            }

            return Math.abs(sum) / 2.0;
        }
     
  9. The issue is that the views are a little flawed here (I had the same problem once). Suppose that you have four blocks in a square. These blocks have the coordinates (0/0), (0/1), (1/0), (1/1). The area should be fairly simple, right? Just subtract x from x and y from y to get:
    a = (x2 - x1) * (y2 - y1) = (1 - 0) * (1 - 0) = 1 * 1 = 1. Wait what? How's that 1 and not 4? Well here's the logic flaw.
    The coordinate of a block is the lower, left corner of the block. Now to calculate the area of a square, we need to get the "highest" x minus the "lowest" x of that square, multiplied by the "highest" y minus the "lowest" y. But we only have the "lowest" x and "lowest" y at hand. In other words, if we're looking at the "highest" x and "highest" y, we'll need to add 1 (individually). If we're looking at the lowest, we can leave that as it is.
     
  10. Thank you. But how would I know if I am looking at the lowest or highest?
    Do you have any code example?