Click here to Skip to main content
15,904,024 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
I'm trying to get a simple spin effect for an object defined by RECT structure and I'm having a little bit of trouble with the math of it.

Here is what i have so far

C++
int moveAroundHimself(RECT &r, RECT limit, double step, int id) {
	static double info[100][10] = {};
	if(!info[id][0]) {
		info[id][0] = r.left;
		info[id][1] = r.right;
		info[id][2] = r.top;
		info[id][3] = r.bottom;
		info[id][4] = 0;
		info[id][5] = (r.right + r.left)/2; // xCenter
		info[id][6] = (r.bottom + r.top)/2; // yCenter

	}
	// xRot = xCenter + cos(Angle) * (x - xCenter) - sin(Angle) * (y - yCenter)
	// yRot = yCenter + sin(Angle) * (x - xCenter) + cos(Angle) * (y - yCenter)
	r.left = info[id][5] + cos(info[id][4]) * (info[id][0] - info[id][5]) - sin(info[id][4]) * (info[id][2] - info[id][6]);
	r.right = info[id][5] + cos(info[id][4]) * (info[id][1] - info[id][5]) - sin(info[id][4]) * (info[id][3] - info[id][6]);
	r.top = info[id][6] + sin(info[id][4]) * (info[id][0] - info[id][5]) + cos(info[id][4]) * (info[id][2] - info[id][6]);
	r.bottom = info[id][6] + sin(info[id][4]) * (info[id][1] - info[id][5]) + cos(info[id][4]) * (info[id][3] - info[id][6]);


	info[id][4] += step;

	return 0;

}

You can ignore the limit rect for now.

Any idea on what is wrong ?
Posted
Updated 4-Apr-13 9:20am
v3
Comments
Captain Price 4-Apr-13 11:23am    
Do you want to rotate the RECT ?
ionutvmi 4-Apr-13 11:25am    
yes around his center like he is spinning
Captain Price 4-Apr-13 11:34am    
You mean only 4 rotations; to left, to top, to right & to bottom ?
ionutvmi 4-Apr-13 11:44am    
no i mean like this http://i.imgur.com/uBlN7Uc.png

the left,top,right,bottom are it's coordinates http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897(v=vs.85).aspx
nv3 4-Apr-13 11:47am    
You are rotating around the origin of the coordinate system and not the center of the rect.

1 solution

Here is a version that calculates the rotation in relation to the rectangle's center.
C++
RECT RotateRect (const Rect& r, double angle)
{
    double sina = sin (angle);
    double cosa = cos (angle);

    double xc = (r.left + r.right) * 0.5;
    double yc = (r.top + r.bottom) * 0.5;

    double w2 = r.right - xc;   // half the width
    double h2 = r.bottom - yc;  // half the height

    double dx = cosa * w2 - sina * h2;
    double dy = sina * w2 + cosa * h2;

    RECT q;
    q.left   = xc - dx;
    q.top    = yc - dy;
    q.right  = xc + dx;
    q.bottom = yc + dy;
    return q;
}

I have removed that static array, which actually belongs into the calling code. The function returns the rotated rectangle. I didn't take the time to debug that code, leaving that as an exercise for you.

Note that movement of the corners is symmetrical. Hence we need to calculate the new corner vector only once, and then add repsectively subtract it from the center.
 
Share this answer
 
v3
Comments
ionutvmi 4-Apr-13 14:47pm    
hello, thanks for your reply but that seems to shrink it down till it's gone and it's not rotating at all...
nv3 4-Apr-13 15:02pm    
The sign in the line dy = ... was inverted.
ionutvmi 4-Apr-13 15:17pm    
it's changing it's shape and it moves it to the right corner,
i also got to something similar witch seems to be stationary but instead of rotating it's changing it's shape (width and height) exactly like yours(i updated the question).

i just can't figure out why is doing that...
nv3 4-Apr-13 15:49pm    
The code looks mathematically correct. My guess is that is has to do with the code outside, which you haven't shown.

Also, the initial test "if (!info[id][0]) ..." is a great way to get caught. What if r.left is initially zero?

I would just step through it with de debugger. If you are not familiar with that, do at least a test print of a couple of iteration, each with in- and out-coords. Then it should become obvious what's happening.
Sergey Alexandrovich Kryukov 4-Apr-13 15:59pm    
I trust it works correctly, the idea is right... a 5.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900