library(dplyr)
## Warning: package 'dplyr' was built under R version 4.1.3
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
Example
x=c(rep(0,500),seq(0,1,length.out=1000), rep(1,500))
y=c(seq(-1,1,length.out=500),rep(0,1000), seq(-1,1,length.out=500))
z=rbind(x,y)
plot(y~x, xlim=c(-3,3), ylim=c(-3,3))

Initials
x=c(rep(0,500),seq(0,0.5,length.out=250),seq(0.5,1,length.out=250), rep(1,500), rep(2,500), seq(1.5,2.5,length.out=500),seq(1.5,2,length.out=500))
y=c(seq(-1,1,length.out=500),seq(1,0,length.out=250),seq(0,1,length.out=250), seq(-1,1,length.out=500), seq(0,1,length.out=500), rep(1,500),cos(seq(pi/1.8,(3*pi)/2,length.out=500)))
z=rbind(x,y)
plot(y~x, xlim=c(-3,3), ylim=c(-3,3))

Identity Matrix
identity <- diag(2)
leftMultiply <- function(x,y){
x %*% y
}
Shear
for (i in seq(0,1,length.out=40)) {
identity[2,1]<-i
z1<-apply(z,2,function(x) leftMultiply(x,identity))
plot(z1[2,]~z1[1,], xlim=c(-3,3), ylim=c(-3,3))
}

Scale
identity<- diag(2)
for (i in seq(0,1,length.out=40)) {
identity[2,2]<-i
identity[1,1]<-i
z1<-apply(z,2,function(x) leftMultiply(x,identity))
plot(z1[2,]~z1[1,], xlim=c(-3,3), ylim=c(-3,3))
}

Rotate
#2pi is a full circle rotation
for (i in seq(0,2*pi,length.out=40)) {
identity<-matrix(c(cos(i),-sin(i),sin(i),cos(i)),nrow=2,ncol=2)
z1<-apply(z,2,function(x) leftMultiply(x,identity))
plot(z1[2,]~z1[1,], xlim=c(-3,3), ylim=c(-3,3))
}

Projection
z.threeD<-rbind(z,rep(0, ncol(z)))
for (i in seq(0,pi/2,length.out=40)) {
identity<- matrix(c(1,0,0,0,cos(i),-sin(i),0,sin(i),cos(i)),nrow=3,ncol=3)
z1<-apply(z.threeD,2,function(x) leftMultiply(x,identity))
plot(z1[2,]~z1[1,], xlim=c(-3,3), ylim=c(-3,3))
}
