Letters

First we Need to write out our initials. Unfortunately I have two annoyingly complex letters S and R to “write”. Using a translated sin curve works for the S and the a partial sin curve for the curve of the R (with a bit of overrun to give it some style), and straight lines are used for the balance of the R.

x=c(sin(seq(-pi*.3,pi*2.3,length.out=2000))/2-1, rep(0,500),
sin(seq(pi*-.1,pi,length.out=1000)), seq(0,1,length.out=500))

y=c(seq(-1,1,length.out=2000),
    seq(-1,1,length.out=500), seq(1,0,length.out=1000),
    seq(0,-1,length.out=500))

z=rbind(x,y)

plot(y~x, xlim=c(-3,3), ylim=c(-3,3))

It is possibly a little imperfect, but legible enough.

Function

We next have to write a simple function to apply a matrix, we then test it with a simple identity matrix to verify that it is working

ourMatrixMult <- function(x,y){
   x %*% y
}
ourMatrixMult(matrix(rep(seq(1,3, length.out=3),3), nrow = 3, ncol = 3),diag(3))
##      [,1] [,2] [,3]
## [1,]    1    1    1
## [2,]    2    2    2
## [3,]    3    3    3

Animation

Shear

Vertical

For a vertical shear we increase above 0 the element at the lower left corner of the identity matrix. As we increase it elements further away from the 0 line on the y axis are pulled either right (if positive) or left (if negative).

for (i in seq(0,4,length.out=20)) {
  newZ<-apply(z,2,function(x) ourMatrixMult(x,matrix(c(1,i,0,1),nrow=2,ncol=2)))
   plot(newZ[2,]~newZ[1,], xlim=c(-3,3), ylim=c(-3,3))
}

Shearing rapidly degrades intelligibility, but this can be corrected by viewing the paper from extreme off angles (Anamorphosis). #### Horizontal For horizontal we do a similar transformation but to upper right element. This will not affect 0 line elements but pull positive x elements up and negative ones down.

for (i in seq(0,4,length.out=20)) {
  newZ<-apply(z,2,function(x) ourMatrixMult(x,matrix(c(1,0,i,1),nrow=2,ncol=2)))
   plot(newZ[2,]~newZ[1,], xlim=c(-3,3), ylim=c(-3,3))
}

Scaling

Scaling can be thought of as simple multiplication (or division) of the values.

UpScale

For upscaling instead of using an identity matrix we use a gradually increasing above 1 value where the 1 would be.

for (i in seq(1,4,length.out=20)) {
  newZ<-apply(z,2,function(x) ourMatrixMult(x,matrix(c(i,0,0,i),nrow=2,ncol=2)))
   plot(newZ[2,]~newZ[1,], xlim=c(-3,3), ylim=c(-3,3))
}

Scaling up allows one to see the point symbols perhaps a bit too clearly and might be a reason to use a connected drawing system. #### DownScale In our downscaling example we simply change it from an identity matrix to a progressively smaller diagonal decimals. We also have reduced the size of the point symbol to make the smaller view a bit more intelligible.

for (i in seq(1,.1,length.out=20)) {
  newZ<-apply(z,2,function(x) ourMatrixMult(x,matrix(c(i,0,0,i),nrow=2,ncol=2)))
   plot(newZ[2,]~newZ[1,], xlim=c(-3,3), cex=.5,ylim=c(-3,3))
}

Downscaling beyond a certain point is a lossy process because of the way values are calculated.

Rotation

For rotation we are effectively shear the matrix multiple times using some trigonometric functions. Note that we have to the aspect ration to a square value to avoid the plot from appearing distorted.

for (i in seq(0,pi*2,length.out=20)) {
  newZ<-apply(z,2,function(x) ourMatrixMult(x,matrix(c(cos(i),-sin(i),sin(i),cos(i)),nrow=2,ncol=2)))
   plot(newZ[2,]~newZ[1,], xlim=c(-3,3), ylim=c(-3,3))
}

Note that a full cycle is 2 pi.

Projection

Projection requires a 3d (or at least more dimensions than we are projecting upon) space which we simply set the existing values to be at the 0 Z axis. We then alter the projection to rotate around the Z axis.

for (i in seq(0,2*pi,length.out=20)) {
  triZ<-rbind(z,rep(0,ncol(z)))
  newZ<-apply(triZ,2,function(x) ourMatrixMult(x,matrix(c(1,0,0,0,cos(i),-sin(i),0,sin(i),cos(i)),nrow=3,ncol=3)))
   plot(newZ[2,]~newZ[1,], xlim=c(-3,3), ylim=c(-3,3))
}

Again, and perhaps unsurprisingly we have a full cycle being 2 pi.