We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › get current traslation
Page Index Toggle Pages: 1
get current traslation? (Read 1804 times)
get current traslation?
Jun 28th, 2007, 12:40am
 
Is there some way to find out how much the coordinate system is currently translated?

For example, i have a class Button that I translate to the right coordinates. But in the button-class I want to be able to find out if the mousepointer is hovering the button. The problem is that i don't know any way of doing that because in the class i don't know how much the system is translated.

Any solution?
Re: get current traslation?
Reply #1 - Jun 28th, 2007, 4:36pm
 
Hi murtlest,

I've been dealing with this same issue while trying to implement some basic GUI elements in Processing, too.

The main idea is to translate the mouse position, which is currently in "screen" coordinates, into "model" coordinates. This works as long as we can assume that the model is on a flat plane parallel to the screen, and it should be simple enough to do by taking the inverse of the model's transformation matrix, and using that to transform our point.

Check out the following code sample for a simple case of translating the screen mouse coordinates to the model coordinates using P3D. Note that this WILL NOT work using Java2D -- the Java2D PGraphics class currently doesn't fill the modelview and modelviewInv matrices with anything useful. I'll be submitting a bug report about this soon.

Quote:


float leftEdge = 20;
float topEdge = 20;
float w = 20;
float h = 20;
color fillColor = color(255,255,255);

void setup() {
 size(300,300,P3D);
}

void hitDetectMyRect() {
 // Retrieve the inverse modelview matrix.
 PMatrix mat = g.modelviewInv;
 // Translate the mouse coordinates by half screen size.
 // (this is necessary because of how P3D uses transforms)
 float mx = mouseX - width/2;
 float my = mouseY - height/2;
 // Transform the mouse coordinates using the inverse matrix.
 float modelX = mx*mat.m00 + my*mat.m01 + mat.m02 + mat.m03;
 float modelY = mx*mat.m10 + my*mat.m11 + mat.m12 + mat.m13;
 // Do a simple rectangular hit detection.
 if (modelX < leftEdge || modelX > leftEdge + w ||
     modelY < topEdge  || modelY > topEdge + h)
 {
   fillColor = color(255,255,255);
   return;
 }
 fillColor = color(255,0,0);
}

void draw() {
 background(255);
 // Translate, rotate, and scale the stage.
 translate(width/2,height/2);
 rotate(frameCount * (PI / 300));
 scale( cos(frameCount * (PI / 300)));
 // Hit detect.
 hitDetectMyRect();
 // Draw the rectangle.
 fill(fillColor);
 rect(leftEdge,topEdge,w,h);
}




I hope this helps!

An aside: if you're doing your programming from outside of Processing (i.e. using another Java IDE and making your class extend PApplet), let me know -- I'm developing a simple static class that helps translate between screen and model coordinates. I haven't tested it extensively, but it may be of some use to you.

Cheers,
 greg
Re: get current traslation?
Reply #2 - Jun 28th, 2007, 7:22pm
 
Whoops, I just found a more "correct" way to do the matrix transforms. I had been subtracting half the screen width and height, but I should have been applying both the camera AND inverse model matrices. Below is an improved version:

Quote:


float leftEdge = 20;
float topEdge = 20;
float w = 20;
float h = 20;
color fillColor = color(255,255,255);

void setup() {
 size(300,300,P3D);
}

void hitDetectMyRect() {
 // Retrieve the relevant matrices.
 PMatrix cam = g.camera;
 PMatrix mvi = g.modelviewInv;  
 // First, transform along the camera matrix.
 float z = 0;
 float aX = mouseX*cam.m00 + mouseY*cam.m01 + z*cam.m02 + cam.m03;
 float aY = mouseX*cam.m10 + mouseY*cam.m11 + z*cam.m12 + cam.m13;
 // Next, transform along the modelviewInv matrix.
 float modelX = aX*mvi.m00 + aY*mvi.m01 + z*mvi.m02 + mvi.m03;
 float modelY = aX*mvi.m10 + aY*mvi.m11 + z*mvi.m12 + mvi.m13;
 // Do a simple rectangular hit detection.
 if (modelX < leftEdge || modelX > leftEdge + w ||
     modelY < topEdge  || modelY > topEdge + h) {
   fillColor = color(255,255,255);
 } else {
 fillColor = color(255,0,0);
 }
}

void draw() {
 background(255);
 // Translate, rotate, and scale the stage.
 translate(width/2,height/2);
 rotate(frameCount * (PI / 300));
 scale( cos(frameCount * (PI / 300)));
 // Hit detect.
 hitDetectMyRect();
 // Draw the rectangle.
 fill(fillColor);
 rect(leftEdge,topEdge,w,h);
}


Re: get current traslation?
Reply #3 - Jun 29th, 2007, 1:22am
 
use screenX() and screenY() to get the coordinates of the button in screen space, then check to see if the mouse is inside.
Re: get current traslation?
Reply #4 - Jun 29th, 2007, 12:26pm
 
But screenX() wants 3 input parameters? I tried to do something like this:

Code:

public boolean isOver(){
return mouseX>screenX()&&mouseX<screenX()+10&&mouseY>screenY()&&mouseY<screenY()+10;
}


but what should the in-parameters be?


gjuggler's hack is working fine, thank you very much. But of course it seem's much easier to just use screenX() if i could get it to work.
Re: get current traslation?
Reply #5 - Jun 29th, 2007, 12:29pm
 
See http://processing.org/reference/screenX_.html
Re: get current traslation?
Reply #6 - Jun 29th, 2007, 12:30pm
 
Ah I just use screenX(0,0,0). Works perfect.

Thanks a lot!
Re: get current traslation?
Reply #7 - Jun 29th, 2007, 7:20pm
 
The problem with using screenX() is that once you get the button coordinates into screen space, you then have to calculate the hit detection on an arbitrarily rotated and scaled rectangle. Not only is this annoying to program, but it adds needless computations to your loop.

If you instead bring the screen coordinates into model space, (a) it's no more computationally intensive than going from model to screen, and (b) you get to use a much simpler, faster rectangular hit detection that will work given any rotation or scale.

At least, this is the way I see things. Is there something wrong with my logic, or perhaps I am missing something obvious?

I understand that formally there is no way to go from screen to model coordinates in 3D because of the non-invertible projection matrix, but for those of us using P3D for 2D drawing as a faster alternative to Java2D, I would argue that having a simple method for converting from screen to "parallel plane" model coordinates would be very useful. Anyhow, that's just my two cents.
Re: get current traslation?
Reply #8 - Aug 24th, 2009, 10:57am
 
I really would like to be able to retrieve the transformation matrices of PGraphics, just as pjuggler demonstrated. Somehow the render context seems not to be addressed (any more?).

Code:

// Retrieve the relevant matrices.
PMatrix cam = g.camera;
PMatrix mvi = g.modelviewInv;  


This part of the code gives me the error "g.camera cannot be resolved or is not a field".
I have also tried this, based on an old post by fry:

Code:

PGraphics3D p3 = (PGraphics3D) g;
PMatrix3D proj;

void setup() {
 size(100, 100, P3D);
 proj = p3.projection;
}


This throws a NullPointerException Error Sad
Does anyone have an idea how I can get the transformation matrices???
Re: get current traslation?
Reply #9 - Aug 24th, 2009, 3:21pm
 
mustermann wrote on Aug 24th, 2009, 10:57am:
Code:

PGraphics3D p3 = (PGraphics3D) g;
PMatrix3D proj;

void setup() {
 size(100, 100, P3D);
 proj = p3.projection;
}


This throws a NullPointerException Error Sad
I think can at least answer this one... I believe that before setup, g isn't initialized. You should try to assign p3 in setup().
Re: get current traslation?
Reply #10 - Aug 25th, 2009, 2:18am
 
Hey PhiLho,
thanks!!! In a short test there are no more errors, will now try to implement. Looks like it solved my problem.
Page Index Toggle Pages: 1