Thread: 2d Transformations : Is the following correct ?

  1. #1
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657

    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 ?
    2d Transformations : Is the following correct ?-2d_trans-png

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    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]
    Your rotation matrix looks like:
    Code:
    [x'] = [cos t  -sin t] [x]     where t is theta, your angle of rotation
    [y']   [sin t   cos t] [y]
    And your translation matrix is a 1x2 matrix that you add instead of multiply:
    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).
    Last edited by anduril462; 05-15-2012 at 10:09 AM. Reason: Fixed rotation matrices

  3. #3
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by anduril462 View Post
    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.
    Last edited by manasij7479; 05-15-2012 at 09:46 AM.

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by manasij7479 View Post
    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?

  5. #5
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by anduril462 View Post
    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.

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    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.

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by manasij7479 View Post
    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.

  8. #8
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by anduril462 View Post
    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.
    Last edited by manasij7479; 05-15-2012 at 10:26 AM.

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    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.
    Last edited by anduril462; 05-15-2012 at 10:26 AM.

  10. #10
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    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).

  11. #11
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    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.

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

    Soma
    Last edited by phantomotap; 05-15-2012 at 11:15 AM.

  12. #12
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by phantomotap View Post
    From the example, it seems you also want translation (movement). Is that correct?
    Yes.. that is where the 3x3 matrix comes from.

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

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

    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.

  13. #13
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    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.

    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.

    Create your translation matrix.
    Create your rotation matrix.
    Create your scaling matrix.

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

    [Edit]
    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

  14. #14
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by phantomotap View Post
    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.

    [Edit]
    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.
    2d Transformations : Is the following correct ?-img_2740-jpg
    Note that the circled points are generated randomly.. under constrains (and a,b,c,d are derived with some algebra) .
    Last edited by manasij7479; 05-15-2012 at 11:53 AM.

  15. #15
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. OpenGL Transformations
    By Homunculus in forum Game Programming
    Replies: 4
    Last Post: 11-01-2011, 05:21 PM
  2. Numerical System Transformations - Lecture
    By vurdlak in forum C++ Programming
    Replies: 2
    Last Post: 03-16-2006, 08:16 AM
  3. opengl model transformations
    By curlious in forum Game Programming
    Replies: 3
    Last Post: 09-06-2004, 02:30 PM
  4. DirectX transformations
    By confuted in forum Game Programming
    Replies: 9
    Last Post: 08-02-2003, 07:41 PM