Dot Product to Projection to Rotation

This notebook illustrates the dot product in 2D as a projection onto basis vectors. This approach to understanding rotation is preferable to standard trigonometry heavy approaches because it develops a key intuition for establishing 2D and 3D reference frames in terms of desired directions rather than angles and trig. functions

Ross Beveridge

August 28, 2018

As will be common in these notebooks, the next sequence of commands configure options for running the notebook such as how to display math, etc.

In [27]:
%display latex
latex.matrix_delimiters(left='|', right='|')
latex.vector_delimiters(left='[', right=']')

The next block of code create two vectors, u and v, that are each of unit length and also perpendicular (orthogonal). Already note that the direction of the 'horizontal' axis defined by the basis vector u is initially specified by picking to arbitrary scalars. Here you see what is meant in lecture about not ever thinking about angles, cosines, etc.(no thetas here).

In [28]:
u = vector([5,-2])
u = 1/u.norm() * u
v = vector([-u[1],u[0]])
u, v
Out[28]:

Just to confirm, notice the dot product confirms orthogonality. In other words, the dot product of one basis vector with the other yields a result of zero.

In [29]:
v.dot_product(u)
Out[29]:

To illustrate projection it is handy to create a geometric object. Specifically, a polygon defined by six points that form an asymetric shape. This asymmetry will prove useful as we use this shape in future examples illustrating different types of 2D transformations. Also, as may be commented upon during lecture, these examples are already hinting at some important practical features of common 2D drawing packages (such as we are exploiting here.)

In [30]:
el = matrix([[1,1],[3,1],[3,2],[2,2],[2,4],[1,4]])
el.transpose()
gel = polygon(list(el),color='green')
In [31]:
bnd = 5.0
gu = arrow((0,0),u)
gv = arrow((0,0),v)
gud = line([(0,0),bnd*u], linestyle="-.")
gvd = line([(0,0),bnd*v], linestyle="-.")
gos = gu + gv + gud + gvd + gel
gos.show(xmin=-bnd, ymin=-bnd, xmax=bnd, ymax=bnd, aspect_ratio=1)

We are now ready to 'see' how this polygon appears in the u,v reference frame. That means projecting each point in the polygon onto the u and the v unit length basis vectors. But, and this is key, keep in mind that one way to compute a dot product is to multiply a row vector times a column vector. Also, if we can do this for a single column vector, we can do it for six column vectors by placing them - one column at a time - into a matrix. So, below you see first all the u-axis coordinates of the projected polygon and then on the next line all the v-axis coordinates of the polygon.

In [32]:
pretty_print(u,el.transpose(),"=",u*el.transpose())
pretty_print(v,el.transpose(),"=",v*el.transpose())

Now for one more simplification. There is no good reason to do these steps seperately. Placing the basis vectors u and v into the top and bottom row of a matrix lets us accomplish the entire operation in a single matrix multiplication.

In [33]:
MM = matrix(2,2,[u,v])
eluv = MM*el.transpose()
pretty_print(MM,el.transpose(),"=",eluv)

Our story is essentially complete when we plot (see below) the polygon as it appears when the u-axis is treated as the horizontal axis and the v-axis is treated as the vertical axis. Rotation can - and generally should - be thought of as the process of projecting a object's vertices onto a new set of mutually orthogonal unit length basis vectors. And, using standard linear algebraic formulations, that means multiplying a rotation matrix by a second matrix containing vertices.

In [34]:
bnd = 5.0
gel = polygon(list(eluv.transpose()),color='orange')
gos = gel
gos.show(xmin=-bnd, ymin=-bnd, xmax=bnd, ymax=bnd, aspect_ratio=1)