Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

2D Math Problem

Started by Josheir Dec 11, 2017 at 3:55 AM 10 replies 4.7k views
Original Post
Josheir
Josheir

In the following code:



Point p = a[1];  center of rotation

for (int i = 0; I<4; i++)
{
 	int x = a.x - p.x;
 	int y = a.y - p.y;
 	
   	a.x = y + p.x;
   	a.y = - x + p.y;
}


I am understanding that a 90 degree shift results in a change like:

xNew = -y

yNew = x


Could someone please explain how the two additions and subtractions of the p.x and p.y works?


Thank you,

Josheir

cmac
cmac

xNew = -y
yNew = x

This rotates a point/vector around the origin by 90 degrees

The original code snippet does the same (similar -- they're mirrored, so if using the same coordinate system it would be the reverse direction), except it rotates about a point other than the origin, which in this case is the center of the rectangle. It's effectively the same as rotating around the origin, except it offsets by the center point's position in order to treat the center point as the origin.


EDIT: for clarity, the two subtractions move the rectangle points to a position relative to the world origin that is the same as their position relative to their center point. Then they are rotated around the origin, then moved back (the two additions) to be relative to the center point instead of the world origin.

Josheir
Josheir

So, is this correct: The first two p's subtract the offset to regard the point not being the origin. Than the computation is done again and p's are added to re translate it back to the origin.


The array is four integers held to be a shape of a grid of 8 cells (two columns,) It's not really a rectangle.


I was playing around with the values (mirrored or not:)

xNew = -y

yNew = x

and got it working luckily. I find it confusing that the second set of additions uses the first set that subtracts. I think I've got it now but was hoping someone could do a simple explanation if there is anything else to explain!

The way that I got it working was I drew a circle with p.y in the center and a.y on the circumference with the difference being what I assumed to be the y. Likewise for the x values.

Thank you,

Josheir

cmac
cmac

Here's a badly drawn MSPaint depiction of what I described:


badly_drawn_rotation.png.95eb94747244ae9e190dca7cbaf5d303.png

alvaro
alvaro

If you know how to rotate around the origin, you can rotate around any point P like this:

  • translate the whole picture so P becomes the origin,
  • rotate around the origin,
  • translate back so the origin becomes P


Does that help?


Josheir
Josheir

Yes, all that helps; I'm pretty sure I understand it now. I am a bit confused by the diagram though. I'll go over my program again tomorrow but I do understand what you mean. I need to translate this understandable concept into the understandability of the idea for a specific program. Like I said, it's not really a rectangle, it's more complicated.

Thanks again,

Josheir

cmac
cmac

Black dot = polygon center, red line = subtraction, green line = rotation, blue line = addition. As you can see, the point ends up at the desired point (90 degrees rotated around center).

Overall Alvaro's explanation was much more elegant and concise than mine, so just focus on that.

Josheir
Josheir

hmm, cmc where did you translate the whole picture so P becomes the origin?

Appreciatively,

Josheir

cmac
cmac

The subtraction (red line) translates the picture so that the polygon center has become (0,0).

h8CplusplusGuru
h8CplusplusGuru

So in the image, there is P and center. P is a distance from center. The red line is P - C, this puts P a distance from origin. Green line is a rotation around origin = Pr. Blue line is Pr + C, moves the rotated point back out to be around center, and is the final rotated point.

Dirk Gregorius
Dirk Gregorius

This results from the dot product. Say you have a vector u and you are looking for a vector v orthogonal to u. You know that the dot product between two orthogonal vectors must be zero. Hence

u.x * v.x + u.y * v.y = 0

Common sense shows that the simplest solution here is to choose:

v.x = u.y and v.y = u.x and negate either v.x or v.y

E.g choose:

v.x = u.y and v.y = -u.x

And you get

u.x * u.y - u.y * u.x = 0

The same is true for v.x = -u.y and v.y = u.x

Geometrically choosing v.x to be negative is equivalent to a 90 degree CCW rotation around the origin while choosing v.y to be negative represents a 90 degree CW rotation around the origin. This is easy to verify.

You will find the same idea applied in 3D as well. Two coordinates are flipped like in 2D and the third coordinate is chosen to zero. Erin posted an elegant solution in 3D on his blog some years ago:

http://box2d.org/2014/02/computing-a-basis/

HTH,

-Dirk

Topic Locked

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

Sign in to reply to this topic.