Math for translating mouse coordinates

This is a very simplified program showing my problem. I need to draw to an image that is rotated. I can’t use any of processing’s line or point functions because of different type brushes in the real program. I have to draw directly to the pixel data. This program plots 4 black pixels under the mouse when its pressed. It works fine on the image that isn’t rotated, but I need to know how to translate the x and y position so it works when the image is rotated. Here’s the simple program:

PImage img;
float rotation = 0.0;
final float deg45 = 45 * PI /180;

void setup(){
     size(800,800);
     img = createImage(800,800,ARGB);
     img.loadPixels();
     for (int i=0; i < img.pixels.length;i++){
          img.pixels[i] = 0xFFFFFFFF;
     }
     img.updatePixels();
}
void draw(){
     background(0);
     if(rotation != 0.0){     
          pushMatrix();
          translate(img.width/2,img.height/2);
          rotate(rotation);
          translate(-img.width/2,-img.height/2);
     }
     int mx = mouseX;
     int my = mouseY;
     if(mousePressed){
          blot(mx,my);          
     }
     image(img,0,0);
     if(rotation != 0.0)     
          popMatrix();
}
void blot(int x,int y){
     img.loadPixels();
     img.pixels[y * img.width + x] = 0xFF000000;
     img.pixels[y * img.width + x+1] = 0xFF000000;
     img.pixels[y * img.width + img.width + x] = 0xFF000000;
     img.pixels[y * img.width + img.width + x+1] = 0xFF000000;
     img.updatePixels();
}
void keyPressed(){
     if(key == ' '){
          if(rotation == deg45)
               rotation = 0.0;
          else rotation = deg45;
     }
     else if ( key == 'c'){
          img.loadPixels();
          for (int i=0; i < img.pixels.length;i++){
               img.pixels[i] = 0xFFFFFFFF;
          }
          img.updatePixels();          
     }
     
}

I got it I found the answer here :
https://homepages.inf.ed.ac.uk/rbf/HIPR2/rotate.htm
The description is a little off. The angle needs to be in radians and not degrees and for it to work for my needs, I had to find the values of the negative angle.

But this is the translation for the mouse coordinates:


          mx = (int)(cos(-rotation) * (mouseX -img.width/2) -  sin(-rotation) * (mouseY-img.height/2) + img.width/2);
          my = (int)( sin(-rotation) * (mouseX-img.width/2) + cos(-rotation) * (mouseY - img.height/2) + img.height/2);

So this sketch works:

PImage img;
float rotation = 0.0;
final float deg45 = 45 * PI /180;

void setup(){
     size(800,800);
     img = createImage(800,800,ARGB);
     img.loadPixels();
     for (int i=0; i < img.pixels.length;i++){
          img.pixels[i] = 0xFFFFFFFF;
     }
     img.updatePixels();
}
void draw(){
     int mx,my;
     background(0);
     if(rotation != 0.0){     
          pushMatrix();
          translate(img.width/2,img.height/2);
          rotate(rotation);
          translate(-img.width/2,-img.height/2);
          mx = (int)(cos(-rotation) * (mouseX -img.width/2) -  sin(-rotation) * (mouseY-img.height/2) + img.width/2);
          my = (int)( sin(-rotation) * (mouseX-img.width/2) + cos(-rotation) * (mouseY - img.height/2) + img.height/2);
     }
     else{
          mx = mouseX;
          my = mouseY;
     }
     if(mousePressed){
          blot(mx,my);          
     }
     image(img,0,0);
     if(rotation != 0.0)     
          popMatrix();
}
void blot(int x,int y){
     img.loadPixels();
     img.pixels[y * img.width + x] = 0xFF000000;
     img.pixels[y * img.width + x+1] = 0xFF000000;
     img.pixels[y * img.width + img.width + x] = 0xFF000000;
     img.pixels[y * img.width + img.width + x+1] = 0xFF000000;
     img.updatePixels();
}
void keyPressed(){
     if(key == ' '){
          if(rotation == deg45)
               rotation = 0.0;
          else rotation = deg45;
     }
     else if ( key == 'c'){
          img.loadPixels();
          for (int i=0; i < img.pixels.length;i++){
               img.pixels[i] = 0xFFFFFFFF;
          }
          img.updatePixels();          
     }
     
}

You might also be looking for the screenX(), screenY(), modelX(), or modelY() functions?

Check out the Coordinates section of the reference.

I looked at screenX() and screenY() but they gave me the opposite of what I need. It would be as if above, I used rotation instead of -rotation. Thanks for the reply.

In that case, modelX() and modelY() are the opposite of screenX() and screenY(). :slight_smile:

I tried it:
changed :
size (800,800 P3D);

and :

mx = (int)modelX(mouseX,mouseY,0);
my = (int)modelY(mouseX,mouseY,0);

Still doesn’t work. It gives me the opposite of what I need to draw on the pixel data under the mouse pointer. Play with that second sketch I posted ( the one that works). Try screenX()/modelX() etc. and see if you can get it it to paint under the mouse pointer. It would make clearer code. I just can’t get it to work.

Please check this library. It works only for 2D and it is available through the Contribution Manager in the PDE: mouse2DTransformations
.

Kf

Thank you. Does it work with Processing 2.2.1? For performance issues, I still use 2.2.1.

Sorry, I can say as I don’t used version 2. You can try and tell us. You can also check the source code. It is not too dense and you should be able to pin point the transformation there easily, which it should be close to what you have if it is not the same. I just suggest using that library as it is taking care of the transformation for you. However, you can just use what you already have if it is working for you.

Kf

1 Like