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.