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 & HelpPrograms › calculating rectangle points based on angle
Page Index Toggle Pages: 1
calculating rectangle points based on angle (Read 1002 times)
calculating rectangle points based on angle
Jan 19th, 2009, 2:43pm
 
Hello,

I'm trying to make a rectangle, that will contain some buttons. This rectangle will be able to rotate at any angle, so things get a little complicated when trying to calculate if the user presses on a button.
I have an image demonstrating what I need here:

...
...

The question is, do I need to manually calculate the position of all the rectangles-buttons (like the red and the green) when the angle (yellow - a) is known, or it can be done somehow "automatically" through processing
Re: calculating rectangle points based on angle
Reply #1 - Jan 19th, 2009, 5:15pm
 
I think you can use screenX and screenY to map between rotated (and translated/scaled) points and actual (screen) points.
Despite the ref, I found on the forum several examples using two coordinates in default mode.
Re: calculating rectangle points based on angle
Reply #2 - Jan 19th, 2009, 5:51pm
 
Hmm as far as I understand, screenX is for taking a "virtual" 3d point and asking processing to give its x value as shown on the 2d screen. But in my case, i do everything in 2d, so i guess it cannot be used..or not?
Re: calculating rectangle points based on angle
Reply #3 - Jan 21st, 2009, 3:08am
 
I think I might be getting somewhere - I need to rotate the mouse coordinates and compare with the rectangle boundaries like if it was not rotated. However, for this calculation, I want to know a hypothetical position of the mouse:

...

The problem is, how to find (XB, YB) if I already know the radius (r), point A(XA, XB) and the angle f. Can I use atan2() here somehow Help.. :/
Re: calculating rectangle points based on angle
Reply #4 - Jan 21st, 2009, 3:33am
 
you're on the right track. without getting into too much theory you need to transform the mouse co-ordinates back into the local space of the rectangle.

since this is in 2D it's fairly trivial. you need to first translate the mouse coordinates so it's relative to the center of the rectangle in screen space. then rotate the translated coordinates by -f radians.

that should do the trick. let me know if you need more help.
Re: calculating rectangle points based on angle
Reply #5 - Jan 25th, 2009, 7:58pm
 
Actually what I needed was a formula to give the coordinates of a point under certain angle..

I couldn't prove it by myself, but i found it in various places (this is why you always have to read literature before ;p)

x = dx*cos(angle)-dy*sin(angle)
y = dx*sin(angle)+dy*cos(angle)

Thanks for the help!
Re: calculating rectangle points based on angle
Reply #6 - Jan 26th, 2009, 8:11pm
 
yup that's the formula to use! for performance i strongly recommend you rotate the mouse coordinates into the local space of the rectangle, rather than rotating the rectangle coordinates.

it's fewer rotations, and it makes the hit detection (is the mouse inside this the rectangle) trivial to implement.

hth
Re: calculating rectangle points based on angle
Reply #7 - Jan 27th, 2009, 1:38pm
 
I am back! :-D
I tried to use screenX, without success, because actually I needed the reverse operation, which seemed not to be provided by Processing.

I left the sketch a while and get back to it today.

I first used Java's AffineTransform but then I found out that Processing's PMatrix would work fine and would be simpler...

Here is my test sketch, with some unused bits, but the essential is there.
Code:
final static int GRID_ROWS = 4;
final static int GRID_COLS = 6;
final static int GRID_CELL_SIZE = 50;

final static int GRID_WIDTH = GRID_CELL_SIZE * GRID_COLS;
final static int GRID_HEIGHT = GRID_CELL_SIZE * GRID_ROWS;

final static color COLOR_DEFAULT  = #2244FF;
final static color COLOR_ALL_OVER = #FF4422;
final static color COLOR_OVER     = #44FF22;
color cellColor;

float angle;
float noiseScale = 0.01;
float noiseX, noiseY;

float origX, origY;
float gxl;
float gxr;
float gyt;
float gyb;
PVector transform;

// Matrix inverse of the current transform
PMatrix2D inverse = new PMatrix2D();


void setup()
{
 size(800, 800);
 smooth();
 origX = width / 2;
 origY = height / 2;

 gxl = 0;
 gxr = GRID_WIDTH;
 gyt = 0;
 gyb = GRID_HEIGHT;

 noiseX = mouseX; noiseY = mouseY;
 cellColor = COLOR_DEFAULT;
}

void draw()
{
 background(#ABCDEF);

 noiseX += noiseScale; noiseY += noiseScale;
 float noiseVal = noise(noiseX, noiseY);

 angle = noiseVal * TWO_PI;

 ApplyTransform();
 DrawGrid();
}

void ApplyTransform()
{
 translate(origX, origY);
 rotate(angle);
 translate(-GRID_WIDTH/2, -GRID_HEIGHT/2);
 DrawPoint(gxl, gyt);
 DrawPoint(gxl, gyb);
 DrawPoint(gxr, gyt);
 DrawPoint(gxr, gyb);

 getMatrix(inverse);
 inverse.invert();
}

void mouseMoved()
{
 float mx = inverse.multX(mouseX, mouseY);
 float my = inverse.multY(mouseX, mouseY);
 if (mx > gxl && mx < gxr && my > gyt && my < gyb)
 {
   cellColor = COLOR_ALL_OVER;
 }
 else
 {
   cellColor = COLOR_DEFAULT;
 }
}

void DrawGrid()
{
 float mx = inverse.multX(mouseX, mouseY);
 float my = inverse.multY(mouseX, mouseY);

 stroke(0);
 for (int r = 0; r < GRID_ROWS; r++)
 {
   for (int c = 0; c < GRID_COLS; c++)
   {
     if (mx > gxl + c * GRID_CELL_SIZE && mx < gxl + (c + 1) * GRID_CELL_SIZE &&
         my > gyt + r * GRID_CELL_SIZE && my < gyt + (r + 1) * GRID_CELL_SIZE)
     {
       fill(COLOR_OVER);
     }
     else
     {
       fill(cellColor);
     }
     rect(0, 0, GRID_CELL_SIZE, GRID_CELL_SIZE);
     translate(GRID_CELL_SIZE, 0);
   }
   translate(-GRID_CELL_SIZE * (GRID_ROWS + 2), GRID_CELL_SIZE);
 }
}

void DrawPoint(float x, float y)
{
 fill(#FF0000);
 noStroke();
 ellipse(x, y, 5, 5);
}

The nice thing is that you can do as many transforms as you want (translations, scaling, rotations), it will still work, without heavy maths!
Re: calculating rectangle points based on angle
Reply #8 - Jan 28th, 2009, 3:37pm
 
I have no words Smiley

Thanks a lot for the help - I'll try to integrate it in my code to keep it cleaner and see if it will perform better..
There are several points that are not so clear to me yet but I have to spend more time on it..
I'll post here in case I need more help Smiley

Cheers and thanks again!
Re: calculating rectangle points based on angle
Reply #9 - Jan 29th, 2009, 10:52pm
 
in the DrawGrid function this line

Quote:
translate(-GRID_CELL_SIZE * (GRID_ROWS + 2), GRID_CELL_SIZE);

should read

Quote:
translate(-GRID_CELL_SIZE * (GRID_ROWS - (GRID_ROWS-GRID_COLS)), GRID_CELL_SIZE);

that way if you change the number of rows or cols then they will continue to line up in a grid.
Re: calculating rectangle points based on angle
Reply #10 - Jan 29th, 2009, 11:10pm
 
polymonkey wrote on Jan 29th, 2009, 10:52pm:
in the DrawGrid function this line...

Ah, you are right but actually I should have written:
translate(-GRID_CELL_SIZE * GRID_COLS, GRID_CELL_SIZE); (which is what your formula is).
Apparently I mixed up rows and cols and I wondered where this constant came from! :-D
Re: calculating rectangle points based on angle
Reply #11 - Jan 29th, 2009, 11:51pm
 
Nice catch, I was too obsessed with the number to see the double subtraction.
Page Index Toggle Pages: 1