3

I want to turn a rectangle into a parallelogram and back, I only have the points for the two shapes. I don't care about position, just matching the shape.

Is it possible to find a transformation matrix to turn a rectangle into a parallelogram given only the points of the two shapes, if so, how?

I'm a programmer and would like to know for a project, this isn't homework or anything.

SpaceFace
  • 163
  • Not always. For instance, if one of the shapes contains the origin while the other doesn't, then no linear transformation can take one to the other. That said, if you want one to be transformed into the other *up to translation*, then we can always do it. – Fimpellizzeri Dec 11 '17 at 19:59
  • One can describe this with linear algebra. You seem to be asking for a matrix $A=\begin{bmatrix}a&b\c&d\end{bmatrix}$ such that $Ap_1=p'_1, Ap_2=p'_2,\dots$. Expanding this out you will have a collection of eight equations and four unknowns. You may then use standard techniques to determine if a solution exists and if it does the possible values of the unknowns. – JMoravitz Dec 11 '17 at 20:02
  • @Fimpellizieri I should have mentioned that, sorry. I only care about shape and size, not translation. – SpaceFace Dec 11 '17 at 20:02
  • @JMoravitz I understand what you're saying about getting the equations, but I'm not sure what to do with them. I don't know what you mean by "standard techniques." Could you be more specific? – SpaceFace Dec 11 '17 at 22:56
  • @spaceface the system of equations and unknowns will be a linear system and solutions if they exist can be found for example via gaussian elimination. – JMoravitz Dec 11 '17 at 23:15
  • @JMoravitz sorry, it's been a while for me. i had a feeling you would say system of equations. but not i'm not sure how all 8 equations fall into play here. wouldn't i only need 4 equations to match the 4 unknowns since it's linear? also, do i do gaussian elimination twice for each row, or do i combine the equations somehow to get all the terms together? does that matter? – SpaceFace Dec 11 '17 at 23:43

2 Answers2

2

I figured it out, thanks to a hint from the comments by @JMoravitz.

This should work for any pair of parallelograms, not just rectangle to parallelogram.

I did so by forming a system of equations using the first two points of each polygon. I'll be writing my answer in pseudocode.

  • r = the rectangle
  • p = the transformed rectangle (parallelogram)
  • T = transformation matrix

r and p are polygons in the forms [ {x: x1, y: y1}, ...{x: x4, y: y4 } ]

We know that p is the resulting parallelogram after transforming r by T. For each point in the rectangle's polygon, the following holds true; p[i] = T * r[i]. Where i is a placeholder for a point's index. When we expand this into two equations for each coordinate seperately we get this.

p[i].x = r[i].x * T[1][1] + r[i].x * T[1][2]
p[i].y = r[i].x * T[2][1] + r[i].y * T[2][2]

This holds true for any point. What we want to find out are the matrix values. From here, we can build a system of equations, we only need four; two for the X coordinates and two for the Y coordinates. We only care about the first two points, since it's always parallelogram, we can guarantee the other two will follow the same pattern. We get the following.

p[1].x = r[1].x * T[1][1] + r[1].x * T[1][2]
p[2].x = r[2].x * T[1][1] + r[2].x * T[1][2]

p[1].y = r[1].y * T[2][1] + r[1].y * T[2][2]
p[2].y = r[2].y * T[2][1] + r[2].y * T[2][2]

Now to solve the system of equations... I'm lazy, so I'm going to use this site here to do it for me. Remember to do the X and Y coordinate systems separately. And from that, we get the following answers for our matrix values.

T[1][1] = (r[2].x * p[1].y - r[1].x * p[2].y) / (p[2].x * p[1].y - p[1].x * p[2].y)
T[1][2] = (r[2].x * p[1].x - r[1].x * p[2].x) / (p[2].x * p[1].y - p[1].x * p[2].y)
T[2][1] = (r[2].y * p[1].y - r[1].y * p[2].y) / (p[2].x * p[1].y - p[1].x * p[2].y)
T[2][2] = (r[2].y * p[1].x - r[1].y * p[2].x) / (p[2].x * p[1].y - p[1].x * p[2].y)

Here's the final code.

function GetLinearTransformation(r, p)
  return [
    [  (r[2].x * p[1].y - r[1].x * p[2].y) / (p[2].x * p[1].y - p[1].x * p[2].y), 
      -(r[2].x * p[1].x - r[1].x * p[2].x) / (p[2].x * p[1].y - p[1].x * p[2].y) ],
    [  (r[2].y * p[1].y - r[1].y * p[2].y) / (p[2].x * p[1].y - p[1].x * p[2].y), 
      -(r[2].y * p[1].x - r[1].y * p[2].x) / (p[2].x * p[1].y - p[1].x * p[2].y) ]
  ]
end

You'll notice that I negated the second column. I'm not exactly sure why I needed to to this, but I'm guessing it has something to do with the fact that Y values are flipped on the computer.

If I made any errors, please correct me and I'll update the answer.

SpaceFace
  • 163
0

First of all you need a $2\times 2$ matrix, since you work in two dimensions.

The transformation matrix will be something like

$$\Lambda = \begin{pmatrix} a_{xx} & a_{xy} \\ a_{yx} & a_{yy} \end{pmatrix}$$

Where the coefficients denote the transformation of the shapes. A parallelogram has the opposite sides congruent and parallel, hence you will expect $a_{xy} = a_{yx}$ for sure. Those are the "shears" coefficient, if you like.

Enrico M.
  • 26,114
  • Could you clarify what you mean by a_xx and such? – SpaceFace Dec 11 '17 at 20:08
  • @SpaceFace I could write a real tome about, so let me suggest a wondrous video which will clarify you everything: https://www.youtube.com/watch?v=kYB8IZa5AuE&index=4&list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab – Enrico M. Dec 11 '17 at 20:22
  • I know about how linear transformations work, I've used them before, but i'm not sure about the algebra of finding a matrix given the input and output vectors. That's where I'm stuck – SpaceFace Dec 11 '17 at 22:06