0

I am having some trouble figuring out how to determine if a mouseclick event was clicked inside of a rectangle, if the rectangle has been rotated.

Lets say I have a MouseAdapter as simple as this. It just prints out a statement saying that we hit inside the rectangle if the mousePressed was in fact within the rectangle.

MouseAdapter mAdapter = new MouseAdapter() {
    public void mousePressed(MouseEvent e) {
        int xPos = e.getX();
        int yPos = e.getY();
        if(xPos >= rect.x && xPos <= rect.x + rect.width && yPos >= rect.y && yPos <= rect.y + rect.height) {
            System.out.println("HIT INSIDE RECTANGLE");
        }
    }
};

My issue comes from when I rotate the rectangle. The if statement above obviously doesn't consider the rotation, so after I rotate the rectangle, my hit test fails. For rotate, I'm doing something as simple as this in a paint() function:

class drawRect {

    Rectangle rect = new Rectangle();

    ...

    public void paint(Graphics g) {
        Graphcis2D g2 = (Graphics2D) g;
        AffineTransform old = g2.getTransform();
        g.rotate(Math.toRadians(90), rect.x, rect.y); 
        g2.draw(rect);
        g2.setTransform(old);
    }
}

This is just some quick pseudocode, so that you guys can understand what I am trying to do. So please don't worry about syntax and all of that. Any help would be appreciated!

Tesla
  • 822
  • 2
  • 13
  • 27
  • I think Rectangle class already doing this look: http://docs.oracle.com/javase/7/docs/api/java/awt/Rectangle.html#contains(int, int) – emin Feb 08 '13 at 20:33
  • There's also a working example [here](http://stackoverflow.com/a/2244285/230513). – trashgod Feb 09 '13 at 02:03

1 Answers1

2

You could apply the rotation to your mouse coordinates as well. Dry-coded:

MouseAdapter mAdapter = new MouseAdapter() {
    public void mousePressed(MouseEvent e) {
        // Create the same transform as used for drawing the rectangle
        AffineTransform t = new AffineTransform();
        t.rotate(Math.toRadians(90), rect.x, rect.y);
        Point2D tp = t.inverseTransform(e.getPoint());

        if(rect.contains(tp)) {
            System.out.println("HIT INSIDE RECTANGLE");
        }
    }
};
Mike Tunnicliffe
  • 10,674
  • 3
  • 31
  • 46
  • My rect.contains() still seems to be returning the boundary box from its original position (before the rotation). I edit 2nd piece of code to reflect what I do a bit more accurately. Is there something I need to update in my 'rect' object after I rotate it, so that the contains() reflects its new position? – Tesla Feb 08 '13 at 21:16
  • Also, the line 'Point2D tp = t.transform(e.getPoint());' seems invalid, as the transform function takes in (at least) 2 points as parameters. – Tesla Feb 08 '13 at 21:32
  • Sorry for the multiple posts! But I actually didn't have to transform the point. I actually used your method to create a new shape that is basically the rectangle with the applied transformation. Then my original e.getPoint() was used within the contain(). Thanks! – Tesla Feb 08 '13 at 21:46
  • I think my code needed to do the inverse transform, editing to (hopefully) improve. – Mike Tunnicliffe Feb 09 '13 at 00:08
  • Is something like this possible when having 3d rotations? – clankill3r Jan 08 '19 at 13:20