Texture Coordinates Solve Transform

This is a quick workup of solving for texture coordinates given three pairings. In the next equation the six degree of freedom transformation mapping from a 3D coordinate on a survace and a 2D coordinate in a texture map is expressed using six free variables indicated 'a' through 'f'.

Ross Beveridge, November 21, 2019

In [1]:
var('a', 'b', 'c', 'd', 'e', 'f')
var('x', 'y', 'z')
var('u','v')
TM = Matrix(SR, 2,3, ((a,b,c),(d,e,f)))
UV = Matrix(SR, 2,1, ((u),(v)))
PT = Matrix(SR, 3,1, ((x),(y),(z)))
pretty_print(UV, LatexExpr(" = "), TM, PT)

Now recognize that when given a point in 3D and a point in 2D there are actually two resulting constraint equations that 'a' through 'f' must satisfy. Two constraints and sixe unknowns is not yet enough to fully solve for a transformation, but that will come next.

In [2]:
TMPT = TM * PT
pretty_print(UV, LatexExpr(" = "), TMPT)
eq1 = (UV[0,0] == TMPT[0,0])
eq2 = (UV[1,0] == TMPT[1,0])
pretty_print("Constraint One: \b", eq1)
pretty_print("Constraint Two: \b", eq2)

Now we need to setup the problem of solving for the six free variables based upon known correspondence between three points as expressed before and after applicaiton of the mapping. In other words, three instances of paired points in 3D then 2D. When we do this, we get the following two Y = M X style linear equations. Each is solved by inverting the matrix M. And notice, it is the same matrix in both cases.

In [3]:
var('u1', 'u2', 'u3')
var('v1', 'v2', 'v3')
var('x1', 'y1', 'z1')
var('x2', 'y2', 'z2')
var('x3', 'y3', 'z3')
YU = Matrix(SR, 3,1, ((u1),(u2),(u3)))
YV = Matrix(SR, 3,1, ((v1),(v2),(v3)))
MM = Matrix(SR, 3,3, ((x1, y1, z1),(x2, y2, z2),(x3, y3, z3)))
XU = Matrix(SR, 3,1, ((a),(b),(c)))
XV = Matrix(SR, 3,1, ((d),(e),(f)))
pretty_print(YU, LatexExpr(" = "), MM, XU)
pretty_print(YV, LatexExpr(" = "), MM, XV)

To see how this works in practice, let us setup three points matching three points. Note that the compact form of the constraints is being shown in a single linear algebraid equation.

In [4]:
PTS2Dt = Matrix(SR, 3,2, ((0,0),(0,1),(1,0)))
PTS2D  = PTS2Dt.transpose()
PTS3Dt = Matrix(SR, 3,3, ((1,2,3),(4,4,4),(9,8,8)))
PTS3D  = PTS3Dt.transpose()
pretty_print(PTS2D, LatexExpr(" = "), TM, PTS3D)
In [5]:
PTS3D.is_invertible()
Out[5]:
True
In [7]:
M2 = PTS3D.inverse()
pretty_print(TM, LatexExpr(" = "), PTS2D, M2)
In [12]:
TMnum = PTS2D * M2
pretty_print(TM, LatexExpr(" = "), TMnum)

Confirm that multiplying the transformation matrix with the 3D points yeilds the specified original 2D points

In [13]:
pretty_print(PTS2D, LatexExpr(" = "), TMnum * PTS3D)