Using Homogeneous Coordinates 
to perform linear transformations and translations in (ℝ^2)
Math 221 Linear Algebra
September 28, 2023

T. Ratliff, Wheaton College
ratliff_thomas@wheatoncollege.edu

The functions and some pre-defined shapes

Description

Execute the code block below to have access to the functions and shapes:

	homogeneous[ list_of_points] 
		takes a list of points in (ℝ^2)and returns the list of points with homogenous coordinates in (ℝ^3)
	dehomogeneous[ list_of_points] 
		takes a list of points in (ℝ^3)with homogeneous coordinates and returns the list of points with coordinates in (ℝ^2)
	pointsPlot[ original_points, transformed_points] 
		plots the list original_points in blue and the list transformed_points in red
		It also draws circles around the first two points in each list to show where they get mapped

The predefined shapes are 
	square1
	square2
	square3
	triangle1
	triangle2
	pentagon1
	bart

Be sure to execute this code block

homogeneous[L_] := Table[ Append[L[[i]],1], {i, 1,Length[L]}];
dehomogeneous[L_] :=Transpose[{{1,0,0},{0,1,0}}.Transpose[L]];

pointsPlot[origPts_,trPts_] := Module[ {pRange,mainPlot,origPtsCirc1,origPtsCirc2, trPtsCirc1,trPtsCirc2},
pRange = Max[ {Abs[origPts],Abs[trPts]}]+0.5;

mainPlot=ListLinePlot[{origPts, trPts}, AspectRatio->1,PlotRange->{{-pRange,pRange},{-pRange,pRange}}, PlotStyle->{Blue, Red}, PlotMarkers -> "●",PlotLegends->{"Original", "T(original)"}];

origPtsCirc1=Graphics[{Blue,Thick,Dashed,Circle[origPts[[1]],pRange*0.05]}];
origPtsCirc2=Graphics[{Blue,Thick,Dashed,Circle[origPts[[2]],pRange*0.1]}];
trPtsCirc1=Graphics[{Red,Thick,Dashed,Circle[trPts[[1]],pRange*0.055]}];
trPtsCirc2=Graphics[{Red,Thick,Dashed,Circle[trPts[[2]],pRange*0.105]}];

Show[mainPlot,origPtsCirc1,origPtsCirc2,trPtsCirc1,trPtsCirc2]
];
square1 = { {0,0}, {1,0}, {1,1}, {0,1}, {0,0}};
square2 = { {-0.5,-0.5},{0.5,-0.5},{0.5,0.5},{-0.5,0.5},{-0.5,-0.5}};
square3 = { {1,1},{2,1},{2,2},{1,2},{1,1}};
triangle1 = { {0,0},{1,0},{Cos[Pi/3],Sin[Pi/3]},{0,0}};
triangle2 = { {1,0},{2,0},{Cos[Pi/3]+1,Sin[Pi/3]},{1,0}};
rm={ {Cos[2Pi/5],-Sin[2Pi/5]},{Sin[2Pi/5],Cos[2Pi/5]}};pentagon1 = { {0,1}, rm.{0,1}, rm.rm.{0,1},rm.rm.rm.{0,1},rm.rm.rm.rm.{0,1},{0,1}};
bart = {{3,2},{4,3},{5,4},{7,4},{8,3},{8,2},{9,2.5},{10,2},{11,3},{12,4},{14,4},{15,3},{16,2},{15.5`,9},{16,16},{14,15},{14,17}, {12,16},{11,18},{9,17},{8,18},{6,16},{5,18},{4,16},{3,17},{2,15},{1,16},{2.5,9},{3,2}};

Example of using the commands

Translate the plane by (3,2) by multiplying by a matrix a

Define the matrix a = (({{1, 0, 3}, {0, 1, 2}, {0, 0, 1}}))
(Remember I’ll use lowercase for variables to avoid clashes with built in Mathematica commands.)
Notice that by putting the ‘;’ at the end of the line, we can suppress the output.

a={{1,0,3},{0,1,2},{0,0,1}};
a//MatrixForm

Let’s get the homogenous coordinates of square1

hpts =homogeneous[square1];
hpts //MatrixForm

And we can multiply by a to perform the transformation

a.hpts

Oh, bummer. The matrix a has 3 columns, so our list of points should have 3 rows. 
We need to take the transpose of hpts to be able to multiply by a

htrpts=a.Transpose[hpts];
htrpts//MatrixForm

We’ve got the transformed points, now let’s get them back into (ℝ^2)

trpts=dehomogeneous[htrpts]

Ugh. Our points are in the columns rather than the rows. 
We needed to take the transpose again after the multiplication.

htrpts=Transpose[a.Transpose[hpts]];
trpts=dehomogeneous[htrpts];
trpts//MatrixForm

Okey doke. Now let’s plot our original shape, square1, and its transformed version:

pointsPlot[square1, trpts]

Here’s a template to do all of that in one execution block. 
You can copy and paste this block for your own work. 
You’ll just need to change the matrix a and you can pick another shape to transform, if you want.

a={{1,0,3},{0,1,2},{0,0,1}};
shapeToTransform = triangle1;

a//MatrixForm
hpts =homogeneous[shapeToTransform];
htrpts=Transpose[a.Transpose[hpts]];
trpts=dehomogeneous[htrpts];
pointsPlot[shapeToTransform, trpts]

Rotate the plane by (ℼ/4)radians counter-clockwise about the point (2,1)

We’ll do this in 3 steps:
	1. Translate the point (2,1) to the origin using a1
	2. Rotate the plane by (ℼ/4) radians about the origin using a2
	3. Translate the origin to (2,1) using a3
Then our matrix a = a3.a2.a1

a1 = {{1,0,-2},{0,1,-1},{0,0,1}};
a2 = {{Cos[Pi/4], -Sin[Pi/4],0},{Sin[Pi/4],Cos[Pi/4],0},{0,0,1}};
a3 = {{1,0,2},{0,1,1},{0,0,1}};
a= a3.a2.a1;
shapeToTransform = square1;

a//MatrixForm
hpts =homogeneous[shapeToTransform];
htrpts=Transpose[a.Transpose[hpts]];
trpts=dehomogeneous[htrpts];
pointsPlot[shapeToTransform, trpts]

Some copies of the template for you to use

You’ll need to change the value of the matrix a, and you can pick another shape to transform if you’d like.

a={{1,0,3},{0,1,2},{0,0,1}};
shapeToTransform = triangle1;

a//MatrixForm
hpts =homogeneous[shapeToTransform];
htrpts=Transpose[a.Transpose[hpts]];
trpts=dehomogeneous[htrpts];
pointsPlot[shapeToTransform, trpts]

Here’s another copy

a={{1,0,3},{0,1,2},{0,0,1}};
shapeToTransform = triangle1;

a//MatrixForm
hpts =homogeneous[shapeToTransform];
htrpts=Transpose[a.Transpose[hpts]];
trpts=dehomogeneous[htrpts];
pointsPlot[shapeToTransform, trpts]

And another one

a={{1,0,3},{0,1,2},{0,0,1}};
shapeToTransform = triangle1;

a//MatrixForm
hpts =homogeneous[shapeToTransform];
htrpts=Transpose[a.Transpose[hpts]];
trpts=dehomogeneous[htrpts];
pointsPlot[shapeToTransform, trpts]