Calculating if mouse position is within bounds of a diamond polygon

2k views Asked by At

I have a diamond drawn on a panel and I'm trying to calculate if the mouse position is within its bounds. The problem is trying to the diamond, it needs four coordinates making up four lines to create the shape.diamond

The easy thing to do is to create/fit a square within the bounds of the diamond, but I want to account for the remaining triangular areas outside. I initially thought I trying to calculate the slope between two points and figuring out if the x and y of the mouse intersects the line by adding the slope into the the equation, but it proved to be a lot more difficult when it comes to the lines that make up the TOP->RIGHT, RIGHT->BOTTOM and BOTTOM->LEFT given that the center of the diamond is not zero.

Is there an easier implementation to check if the mouse's x,y is within the bounds of the diamond?

1

There are 1 answers

6
Joop Eggen On BEST ANSWER

In pseudo-code (to be more readable):

Point org = new Point(64, 32); // Center.
Point radii = new Point(32, 16); // Half the size.

Point mousePos = ...

mousePos -= org; // Relative to the center.
boolean inside = Math.abs(mousePos.x) * radii.y + Math.abs(mousePos.y) * radii.x
                 <= radii.x * radii.y;

Of math one knows (0, radii.y) and (radii.x, 0) determine the border line in the positive quadrant. That comes down to the formula above.

static boolean isInsideDiamond(int x, int y, int[] xs, int[] ys) {
    int minX = xs[0];
    int maxX = minX;
    int minY = ys[0];
    int maxY = minY;
    for (int i = 1; i < 4; ++i) {
        minX = Math.min(minX, xs[i]);
        maxX = Math.max(maxX, xs[i]);
        minY = Math.min(minY, ys[i]);
        maxY = Math.max(maxY, ys[i]);
    }

    int orgX = (minX + maxX) / 2;
    int orgY = (minY + maxY) / 2;
    int radX = (maxX - minX) / 2;
    int radY = (maxY - minY) / 2;

    return isInsideDiamond(x, y, orgX, orgY, radX, radY);
}

static boolean isInsideDiamond(int x, int y, int orgX, int orgY, int radX,
        int radY) {
    x -= orgX;
    x = Math.abs(x);
    y -= orgY;
    y = Math.abs(y);
    return x * radY + y * radX <= radX * radY;
}

By the way:

Polygon diamond = new Polygon(xs, ys, 4);
boolean inside = diamond.contains(x, y);