# 2d Transformations : Is the following correct ?

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 05-15-2012
manasij7479
2d Transformations : Is the following correct ?
I need to transform (part of) a sine curve from the first frame to the second.
Is my matrix correct ?
Attachment 11662
• 05-15-2012
anduril462
Why do you have a 3x3 transformation matrix when you only have a 2-d graph? The result of your transformation should be another 1x2 matrix, representing the new x and y, x' and y'. Also, you are performing 3 transformations. You are scaling, sliding and rotating, so I would use 3 separate 2x2 matrices, one for each transformation. You can combine them later, once you get it. As for the 3 matrices, here is how they work:

1. Scaling: Your old x-axis length was pi/2. The new length needs pythagoreans theorem: sqrt((c-x1)^2 + (d-y1)^2). The scaling factor is new/old. You do similar for the y scaling factor.
2. Rotation: You must figure out how much you rotated by. Make a right triangle with (x1,y1), (c,y1) and (c,d). Use the lengths of the sides to figure out theta, your angle of rotation.
3. Translation: You moved to the right x1 units and up y1 units. You will add this number after you scale and rotate.

Your scaling matrix is just a diagonal. You multiply the x coordinate by the x scaling factor, and the y coordinate by the y scaling factor:
Code:

```[x'] = [Sx  0] [x] [y']  [0  Sy] [y]```
Code:

```[x'] = [cos t  -sin t] [x]    where t is theta, your angle of rotation [y']  [sin t  cos t] [y]```
Code:

```[x'] = [x1] + [x] [y']  [y1]  [y]```
Putting it all together, you get:
Code:

```[x'] = [cos t  -sin t] [Sx  0] [x] + [x1] [y']  [sin t  cos t] [0  Sy] [y]  [y1]```
At least, I'm pretty sure that's how you'd do it. Try taking some points with known cooridanates both before and after, and plug them to see if they transform correctly. Some "easy" known points are (0,0)-->(x1,y1), (0,1)-->(a,b) and (pi/2,0)-->(c,d).
• 05-15-2012
manasij7479
Quote:

Originally Posted by anduril462
Why do you have a 3x3 transformation matrix when you only have a 2-d graph?

Err... it is called Homogeneous coordinates. I thought it simplified things here.
And the (2x2) matrix in the upper left corner is my attempt in combining and simplifying rotation and scaling.
• 05-15-2012
anduril462
Quote:

Originally Posted by manasij7479
Err... it is called Homogeneous coordinates. I thought it simplified things here.
And the (2x2) matrix in the upper left corner is my attempt in combining and simplifying rotation and scaling.

Ahh, clearly you already know more than I do about the subject (screw you work, I'm learning geometry today!)...have you plugged in your know points? Does they transform properly?
• 05-15-2012
manasij7479
Quote:

Originally Posted by anduril462
have you plugged in your know points? Does they transform properly?

The origin does and so does (pi/2,0) but they are simple.
I'm trying to work out if the sine's maxima does.. but the geometry is tripping me up a little.
• 05-15-2012
anduril462
Hmm...I'm pretty sure your setup doesn't work. Your vector should be [x y 1], so you multiply 1 by the translation amounts and add it to your final result. You also need to put [x1 y1 1] across the bottom, not down the right side. It would work on the right side only if you made your horizontal vector vertical and moved it to the right side of your transformation matrix for the multiplication. I'll have to do more reading before I can tell you whether the scale and rotate portion is correct.
• 05-15-2012
anduril462
Quote:

Originally Posted by manasij7479
And the (2x2) matrix in the upper left corner is my attempt in combining and simplifying rotation and scaling.

Can you tell me how you arrived at that simplification, it would probably be easier for me to tell you if you're right that way, then trying to figure out what you did from just that 2x2.
• 05-15-2012
manasij7479
Quote:

Originally Posted by anduril462
Can you tell me how you arrived at that simplification, it would probably be easier for me to tell you if you're right that way, then trying to figure out what you did from just that 2x2.

The fact that the components of the unit vectors (i,j,k) in the new frame as represented from the old frame are the rows of the transformation matrix, in order.
(no k here, though)

EDIT:
It is actually the opposite.
It is the components of the old i and j when transformed into the new frame.
• 05-15-2012
anduril462
I'm pretty sure what you did wont work, it seems to fail when mapping the end of your y axis, (0,1). I get (a-x1, b-y1) when I should just get (a,b).

Given the rotation, you really need some sin/cos values in there. I think you can use the scaling factor matrix and rotation matrix (now fixed -- I had a type) from my first reply, and multiply those to get the upper-left 2x2 for your final matrix. Then just put the translation factors across the bottom, something like:
Code:

```[Sx cos t  -Sy sin t  0] [Sx sin t    Sy cos t  0] [x1          y1        0]```
EDIT: You may need to transpose just the 2x2 scale/translate matrix here, since you're using a row vector on the left instead of a column vector on the right. But you get the idea.
• 05-15-2012
anduril462
Ooh, I think I get it now. The 2x2 for your first matrix appears to be correct, but your vector and translation is wrong for the reasons I mentioned in post #6. Your vector needs a 1, not a 0, and you need to move the translation values to the bottom row. That makes your 3 axis points map correctly. That should be sufficient, but if you want to double check, pick some easier points, like the midpoints of the axis and the midpoint between (0,1) and (pi/2,0) should map to the midpoint between (a,b) and (c,d).
• 05-15-2012
phantomotap
Quote:

And the (2x2) matrix in the upper left corner is my attempt in combining and simplifying rotation and scaling.
O_o

From the example, it seems you also want translation (movement). Is that correct?

I can't follow your example; it also seems like you've updated your matrix since it was posted.

Is this what you have?

Code:

```[X'] [S*COS(A)][ -SIN(A)][H] [X] [Y']=[  SIN(A)][S*COS(A)][K]*[Y] [ 1] [      0][      0][1] [1]```
Where is 'S' is the scale factor, 'A' is the angle of rotation, and ('H', 'K') is the new origin.

If any of these transformation are actually fixed, you can simplify the partial expressions.
[/Edit]

Soma
• 05-15-2012
manasij7479
Quote:

Originally Posted by phantomotap
From the example, it seems you also want translation (movement). Is that correct?

Yes.. that is where the 3x3 matrix comes from.

Quote:

I can't follow your example; it also seems like you've updated your matrix since it was posted.
No

Quote:

Is this what you have?
I think so, only the Scales on x and y being different.

Quote:

If any of these transformation are actually fixed, you can simplify the partial expressions.
That is what led me to construct the simplified version, not calculating the actual angle at all. (and thus avoiding the calls to sin and cos in the inner loop)

I 'think', it works, when following the advice on post#6.
Not tested rigourously yet.
• 05-15-2012
phantomotap
Quote:

Yes.. that is where the 3x3 matrix comes from.
O_o

With homogeneous coordinates scaling, rotation, sheering, translation, and so in two dimensions are all represented by a "3x3" matrix.

I was specifically asking if you were trying to do translations as well because that's what it looks like despite you listing only rotation and scaling.

Quote:

That is what led me to construct the simplified version, not calculating the actual angle at all.
Right, but you don't have to do it that way. I'm not talking about doing it manually.

This can be done in code.

Multiple these three matrices together in an order appropriate to your target.

This resulting matrix can be computed before entering the tight loop to get the `x' and `y' values for the sine wave.
[/Edit]

The result is a matrix with only constant values. You can then multiple that matrix by your point vectors to get the new "position".

Soma
• 05-15-2012
manasij7479
Quote:

Originally Posted by phantomotap
O_o

With homogeneous coordinates scaling, rotation, sheering, translation, and so in two dimensions are all represented by a "3x3" matrix.

I was specifically asking if you were trying to do translations as well because that's what it looks like despite you listing only rotation and scaling.

Obviously... (0,0) to (x1,y1) is definitely translation too.

Quote:

This resulting matrix can be computed before entering the tight loop to get the `x' and `y' values for the sine wave.
[/Edit]

The result is a matrix with only constant values. You can then multiply that matrix by your point vectors to get the new "position".

Soma
I know that !
....there is still one problem (not mentioned above).
I won't generate the whole sine wave in the same coordinates...and the matrix would have to remade for each version.. as opposed to just plugging in the 'random' numbers as with my version.
Here is a rough sketch of a possible output.
Attachment 11664
Note that the circled points are generated randomly.. under constrains (and a,b,c,d are derived with some algebra) .
• 05-15-2012
phantomotap
The "problem" you describe isn't so much of a problem as you apparently think.

If you are only dealing with one transformation each of scaling, rotation, and transformation the combined matrix I posted is sufficient.

It does have to be "baked" (the correct values inserted) but doesn't have to be simplified beyond that to be quite fast. (You only need one extra call to `sin' and `cos'.)

For each frame of reference you "bake" the combined transformation matrix and multiply normally. That's one extra call to `sin' and one extra call to `cos' per frame of reference not per "dot". Each matrix still doesn't have to be created and multiplied every time you sample to get the natural `x' and `y'.

So, to look at your example, you are transforming the sine wave over pairs of third positions. That means you'll be "baking" the transformation matrix once for each consecutive pair. (Which you've helpfully marked with a dotted line.) You'' only need to do this five times for your example. You'll be using each generation as many times as you need to get the fidelity you desire.

If you require a very high quality mapping you'll be sampling `x' and `y' using `sin' far more often than you'll be creating a transformation matrix.

If you are interpolating instead of calling `sin' a lot to get the sine wave you can "bake" the transformation into the interpolation function. Unfortunately, that is beyond my skill; you'll have to wait for VirtualAce or someone else if you want to try that.

Soma
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last