Rotate with scale gives offset results

When the window is sized correctly to 1280 x 800, the line matches up perfectly with the mouse. Otherwise, the line is located below or above the mouse depending on the size of the window.

I have tried placing the rotate command before the scale command, and that seems to do the trick, although the dimensions of the rectangle are wrong whenever the window is stretched horizontally or vertically.

If anyone could shed some light on why the line is offset, I would greatly appreciate it.

void draw() {
  background(255);
  translate(width/2, height/2);

  float scaleX = width / 1280.0;
  float scaleY = height / 800.0;

  scale(scaleX, scaleY);
  rotate(atan2((mouseY - height/2), mouseX - width/2));
  rect(-40, -20, 80, 40);
  line(0, 0, 500, 0);
}

Example 1 Example 2

Tagged:

Answers

  • edited April 2017 Answer ✓

    The reason is that the atan2 method assumes that the aspect ratio is 1. The solution is to transform the mouse position to the new aspect ratio like this

    float scaleX, scaleY;
    
    void setup() {
      size(1500, 900);
      scaleX = width / 1280.0;
      scaleY = height / 800.0;
      println(scaleX, scaleY);
    }
    
    void draw() {
      background(255);
      translate(width/2, height/2);
    
      scale(scaleX, scaleY);
      rotate(atan2((mouseY - height/2)/ scaleY, (mouseX - width/2)/scaleX));
      rect(-40, -20, 80, 40);
      line(0, 0, 500, 0);
    }
    
  • Wow, that was fast. Thank you so much for the quick response, your solution works perfectly :) :)

  • @quark

    mouseX and mouseY are always given from the original frame of reference no matter how many transformations are applied? In the case I need to apply multiple transformations, would I need to keep track of each of them when using mouseX/mouseY?

    I review screenX() and modelX() and I don't think they will help in this situation.

    Kf

  • The problem reported above ONLY happens when the aspect ratio != 1 i.e. when scaleX != scaleY

    In the case I need to apply multiple transformations, would I need to keep track of each of them when using mouseX/mouseY?

    This question is very generic it would depend on the circumstances. In some cases you might want to get the mouseX and mouseY coordinates in a different frame of reference. For instance if you are using G4P you may have a number of controls at different screen positions and rotations (all the G4P controls can be rotated by an arbitrary angle), then when checking mouse interaction with a particular control I calculate the mouse position as if it was in the same frame of reference as the control. It means I can use the same code for controls of the same type e.g. buttons no matter where they are or how rotated they are.

  • @quark In your case, a button is translated and rotated. You will also have to manually applied those transformation to your mouse position then? Just like you did in line 15 (Forgetting for one second about the scale ratio in the original problem). Sorry @BeaconPants, I should have created a fresh new post.

    Kf

  • You will also have to manually applied those transformation to your mouse position then?

    Yes

  • Could you not just apply an inverted transformation (invert the transformation matrix) on the mouseX/mouseY before sending to atan?

Sign In or Register to comment.