Search code examples
mathbukkitpoint-in-polygon

Getting coordinates for regular polygon


I have an indefinite amount of points on a map based around a center. They should be arranged in a polygon, so their angle is 360/amount of points (http://prntscr.com/8z2w3z). I have a center point, a length and directions so it should be possible to find coordinates for the points. As I'm working with Bukkit to create a minecraft plugin the only way to add locations is to add their coordinates, so I can't simply give them a direction. Here is the code I expected to work, but didn't:

        float teamAngle = angle * teamNumber;
        Location spawnPoint = mapCenter;
        float relX = (float)Math.cos(Math.toRadians(teamAngle))*radius;
        float relZ = (float)Math.sin(Math.toRadians(teamAngle))*radius;
        spawnPoint.add(new Location(Bukkit.getWorld("world"), relX, 0, relZ, 0, 0));
  • teamAngle is φ for each point, so with 4 points, it would be 0, 90, 180 and 270
  • radius is simply a float based on the map size/2 * 0.8. It might not be the best variable name

With 4 points, I'd expect something like this (map width 100 => radius 40, center at (0|0) ):

  • A(40|0)
  • B(0|-40)
  • C(-40|040)
  • D(0|40)

EDIT: In fact as a commenter has said, the coords need to be a bit different, i changed it above


Solution

  • Your idea behind calculating the coordinates as far as I can tell is correct. I can only guess that the reason you're getting strange coordinates is because you keep editing the same location over and over again (although since you provided only a partial code snippet I can't guarantee that this is so).

    The line Location spawnPoint = mapCenter does not create a new location, it only creates a reference named spawnPoint pointing to mapCenter.

    The add method for locations also does not return a new Location instance. Since each vertex of the polygon should be found by adding the x and y components to the center location, you must copy or clone the mapCenter variable so that you don't edit/change the original center of the map. I'm assuming that you use a loop to create/find each of the vertex locations of the polygon, and without copying the mapCenter variable, this would happen:

    1st iteration: Angle is 0º, add 40 to the x coordinate of spawnPoint (this changes mapCenter) and 0 to the z coordinate of spawnPoint. Assuming the center of the map was originally at 0, 0, 0, the coordinates are now 40, 0, 0 (this is still correct).

    2nd iteration: Angle is 90º, add 0 to the x coordinate of spawnPoint and 40 to the z coordinate of spawnPoint (once again changing centerMap, which we've already edited in the last iteration). Now the coordinates of mapCenter are 40, 0, 40, which is incorrect. We should have added the new components to a fresh copy of mapCenter.

    To fix this use Location spawnPoint = mapCenter.clone(). Example code:

    public static List<Location> getPolygonVertices(float radius, int edges, Location center) {
        List<Location> vertices = new ArrayList<Location>();
        float angleDelta = 360 / edges; // The change in angle measure we use each iteration
        for (int i = 0; i < edges; i++) { // For each vertix we want to find
            float angle = angleDelta * i; // Calculate the angle by multiplying the change (angleDelta) with the number of the edge
            Location corner = center.clone(); // Clone the center of the map
            corner.add(Math.cos(Math.toRadians(angle)) * radius, 0, Math.sin(Math.toRadians(angle)) * radius); // Add the x and z components to the copy
            vertices.add(corner);
        }
        return vertices;
    }
    

    You could use this method like so:

    List<Location> vertices = getPolygonVertices(40, 4, mapCenter);
    

    and it would return the correct locations ([40|0], [0|40], [-40|0], [0|-40]).