Skip to main content
gamedev.net
🔒 Locked

Triangle Rotation

Started by Supaflyfrank 6 replies 800+ views
Original Post
Supaflyfrank
Supaflyfrank
I am using the Mathematics and Physics for Programmers book and Im trying to apply the rotation formula that they give: x = x coord of one of the vertices. y = y coord of one of the vertices. s = the x coordinate of the center of the polygon t = the y coordinate of the center of the polygon @ = how much i want to rotate the polygon in radians x = sqrt(pow((x-s),2)+pow((y-t),2)) * cos(@-atan((y-t),(x-s))) + s; y = sqrt(pow((x-s),2)+pow((y-t),2)) * sin(@-atan((y-t),(x-s))) + t; here is my code that I have so far. I am jusing the Windows GDI to draw everything. Rect is filled with the different vertices. newx and newy is what i used to supply the center of the polygon/triangle I used the constant double because the compiler complained of not knowing which version of the pow cos sin function to use.



void Paddle::DrawPaddle(HDC hDC)
{
  
    
    HBRUSH hBrush = CreateSolidBrush( RGB(255,0,0));
    HGDIOBJ  oldbrush = SelectObject(hDC,hBrush);
    POINT rect[3];
	int degree = 90;
	double radian = degree*(PI/180);
  
	
    rect[0].x = 100;
    rect[0].y = 100;

    rect[1].x = 150;
    rect[1].y = 200;

    rect[2].x = 50;
    rect[2].y = 200;

	double newx = (rect[0].x+rect[1].x+rect[2].x)*.3333333333333333;
	double newy = (rect[0].y+rect[1].y+rect[2].y)*.3333333333333333;

		rect[0].x = sqrt(pow(rect[0].x-newx,2)+pow(rect[0].y-newy,2))*cos(degree-atan2(rect[0].y-newy,rect[0].x-newx))+newx;
		rect[0].y = sqrt(pow(rect[0].x-newx,2)+pow(rect[0].y-newy,2))*sin(degree-atan2(rect[0].y-newy,rect[0].x-newx))+newy;
	
		rect[1].x = sqrt(pow(rect[1].x-newx,2)+pow(rect[1].y-newy,2))*cos(degree-atan2(rect[1].y-newy,rect[1].x-newx))+newx;
		rect[1].y = sqrt(pow(rect[1].x-newx,2)+pow(rect[1].y-newy,2))*sin(degree-atan2(rect[1].y-newy,rect[1].x-newx))+newy;
	
		rect[2].x = sqrt(pow(rect[2].x-newx,2)+pow(rect[2].y-newy,2))*cos(degree-atan2(rect[2].y-newy,rect[2].x-newx))+newx;
		rect[2].y = sqrt(pow(rect[2].x-newx,2)+pow(rect[2].y-newy,2))*sin(degree-atan2(rect[2].y-newy,rect[2].x-newx))+newy;


Polygon(hDC,rect,3);

    SelectObject(hDC,oldbrush);
    DeleteObject(hBrush);

}


When degree = 90 this is what the debugger says rect[0] = x=160 y=190 rect[1] = x=108 y=189 rect[2] = x=48 y= 198 When degree = 45 rect[0] = x=157 y=250 rect[1] = x=155 y=196 rect[2] = x=98 y= 186 When degree = 135 rect[0] = x=106 y=101 rect[1] = x=54 y=137 rect[2] = x=48 y= 138 the triangle ends up not rotating correctly and I am not sure why it isnt. [Edited by - Supaflyfrank on January 1, 2007 5:23:35 PM]
Vorpy
Vorpy
I'm not sure if this is the problem, but ctan is not doing the same thing as atan2. In fact I'm not really sure what it is trying to do, since I think it has the angles it returns for those special cases backwards. Try using atan2 instead and see if that helps.

That rotation formula also does a lot of unnecessary work, but that's another issue.
Supaflyfrank
Supaflyfrank
i cleaned it up a bit and its still not working any other suggestions?
jdindia
jdindia
Really you should use matrices. I'd recommend reading up on linear algebra somewhere. That aside, your formula is a disaster.


To translate a point by (c,d)
x' = x + c
y' = y + d

To rotate a point about the origin by angle t
x' = x*cos(t) - y*sin(t)
y' = x*sin(t) + y*cos(t)

What you want to do is rotate a point about the center of your polygon. That means you translate the center of the polygon to the origin (0,0) and then you rotate. Finally, you translate back.

If the center of the polygon is (c,d), you want:
x1 = x - c
y1 = y - d

x2 = x1*cos(t) - y1*sin(t)
y2 = x1*sin(t) + y1*cos(t)

x' = x2 + c
y' = y2 + d

Hope it helps.
Vorpy
Vorpy
I would recommend the method posted by jdindia.

After looking more closely at your code, I found some errors. You are using degrees instead of radians, and your formulas are interferring with each other. Your code should look like:
double tempx;tempx = sqrt(pow(rect[0].x-newx,2)+pow(rect[0].y-newy,2))*cos(radian-atan2(rect[0].y-newy,rect[0].x-newx))+newx;rect[0].y = sqrt(pow(rect[0].x-newx,2)+pow(rect[0].y-newy,2))*sin(radian-atan2(rect[0].y-newy,rect[0].x-newx))+newy;rect[0].x = tempx;

You were assigning to x and then using that new value in the following equation to calculate y when you should have been using the old value of x. Also fix this code for the other two points.
Supaflyfrank
Supaflyfrank
Ok I tried that new formula and it works some what. But I have problems with specific values when i input them. degree causes the triangle to be drawn twice as long on each side. And then doesnt rotate correctly and doesnt rotate around its center
[source lang = "cpp"]    const int max = 3;    POINT rect[max];    int degree = 0;    double radian = degree*(PI/180);  	    rect[0].x = 100;    rect[0].y = 100;    rect[1].x = 200;    rect[1].y = 200;    rect[2].x = 100;    rect[2].y = 200;  	double newx = (rect[0].x+rect[1].x+rect[2].x)*(1/3);	double newy = (rect[0].y+rect[1].y+rect[2].y)*(1/3);	double temp, temp1;		temp = (rect[0].x-newx)*cos(radian)-(rect[0].y-newy)*sin(radian) + newx;	temp1 =(rect[0].x-newx)*sin(radian)+(rect[0].y-newy)*cos(radian) + newy;	rect[0].x = temp;	rect[0].y = temp1;	temp = (rect[1].x-newx)*cos(radian)-(rect[1].y-newy)*sin(radian) + newx;	temp1 =(rect[1].x-newx)*sin(radian)+(rect[1].y-newy)*cos(radian) + newy;	rect[1].x = temp;	rect[1].y = temp1;	temp = (rect[2].x-newx)*cos(radian)-(rect[2].y-newy)*sin(radian) + newx;	temp1 =(rect[2].x-newx)*sin(radian)+(rect[2].y-newy)*cos(radian) + newy;	rect[2].x = temp;	rect[2].y = temp1;


When degree = 90--Triangle Disappears
rect[0] {x=-100 y=100}
rect[1] {x=-200 y=200}
rect[2] {x=-200 y=100}


When degree = 180 Triangle Disappears
rect[0] {x=-100 y=-99}
rect[1] {x=-200 y=-199}
rect[2] {x=-100 y=-200}


When degree = 72 Triangle Disappears
rect[0] {x=-64 y=126}
rect[1] {x=-128 y=252}
rect[2] {x=-159 y=156}
Vorpy
Vorpy
The problem is here:
double newx = (rect[0].x+rect[1].x+rect[2].x)*(1/3);

(1/3) evaluates to 0 because 1 and 3 are both integers and integer division truncates the remainder. Use (1.0/3) instead to get double precision division.
Supaflyfrank
Supaflyfrank
Thank you so much! It works perfectly. I never thought something like that happens. Thanks for all the help!!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.