Help with Scale and Mouse Coordinates Mismatch

Hello fellow programmers!
I’ve been working on a small space game, and have run into an issue with the ‘solar system map’ system.
I’m using translations and scale effects to give the illusion of a full, traversable map.

Unfortunately, when trying to convert mouse coordinates over to the transformed version, I get small, seemingly random, offsets.

Here is what I mean:
ezgif.com-gif-maker(1)

The white dot beside my mouse/cursor is where the computer believes me to be clicking inside of the transformation(s).

I’ve tried numerous offsets, but cannot seem to manage to get it to work. Any help would be appreciated.

Code below:

float scale_amt = 0.05;
PVector solar_map_move = new PVector(0,0);
float solar_map_movespeed = 50;
//Movespeed is for the movement inside the map with keyboard controls. Ignore it for the time being.

void solar_system_map(){
 
  float guiWidth = width*0.9-width*0.05;
  float guiHeight = height*0.9-height*0.05;
      //Width and height of the guibox
  float zomWidth = guiWidth*scale_amt;
  float zomHeight = guiHeight*scale_amt;
       //zoomWidth and zoomHeight of the guiSize

  PVector anchor = new PVector(((width*0.9)-zomWidth)/2,((height*0.9)-zomHeight)/2);
      //Where everything should anchor to (in order to prevent weird scaling things)
  
  PVector mouseInMap = new PVector(((((mouseX)/scale_amt))-(guiWidth/scale_amt)/2+solar_map_move.x),((((mouseY)/scale_amt))-(guiHeight/scale_amt)/2+solar_map_move.y)+(15*scale_amt));
//Code I'm using to detect the mouse inside of the transformations.
//Basically: (mouseX*scale) - (guiWidth*scale)/2 + solar_map_move
  
  pushMatrix();
  translate(anchor.x,anchor.y); //Translate by the anchor point to maintain it in the center
  scale(scale_amt,scale_amt); //Scale by the scale amount to change size
  translate(-solar_map_move.x,-solar_map_move.y); //Translate by the movement amount to move around

  ellipse(mouseInMap.x,mouseInMap.y,15/scale_amt,15/scale_amt);
      //Draw an ellipse at the current mouse position. I have the circle size * the scale amount in order to ensure continuity of the 'cursor'

  popMatrix();
//End matrix push

}

I left out a lot of code for the sake of clarity, but you should be able to get the general idea.

Hi! It’s good that you shared the code, but I feel it’s hard to look into it without a working code. I would suggest to make a sketch from scratch, a mini version of what you are trying to do, let’s say

void draw() {
  translate(tx, ty);
  scale(s, s);
  float mx, my;
  // some mouse transform happens
  ellipse(mx, my, 10);
}

to see if you can correctly find the transformation.

1 Like

I’ve done what you said and really looked at the transformations being applied to the mouse. It would appear as if the section in the mouse code: ((guiWidth/scale_amt)/2) breaks when I zoom in or out in roughly any capacity. What’s really weird is the fact that if I try to remove or modify it, it seemingly stops allowing the mouse to be even close to the right location. I’m not sure quite how to fix it, but I believe that it is the reason why this issue is happening. I’ll try to keep you posted on any solutions I may find.

EDIT:
On second observation, it seems as if that wasn’t the issue. Something is offsetting it inside of the actual thingy: (mouseX/scale_amt)+solar_map_move.x)
The extra line: -((guiWidth/scale_amt)/2) appears to not really be the thing affecting it. Instead, it may a be either a combination of the two, or instead something wrong with my math. I’ll try to post another update soon.

And I think I’ve found it!

(mouseX/scale_amt)+(zomWidth/scale_amt)/2)+solar_map_move.x-(guiWidth/scale_amt)/2 
//I can add extra offsets here.

In essence, I take the mouse coordinates:
mouseX * scale amount
and then add
zoom offset width * scale amount (all divided by two)
Then, add the offset to ensure the mouse position does not move when the map moves:
+solar map move
and finally, I subtract a small offset to ensure that the mouse is right over where the user’s mouse is.
-guiWidth * scale amount (all divided by two)
and boom.

2 Likes