射影変換、次元を上げる〜ぱらぱらめくる『射影幾何学入門〜生物の形態と数学〜

射影幾何学入門―生物の形態と数学

射影幾何学入門―生物の形態と数学

  • 昨日の最後の記事は、1次元の射影直線での射影変換
  • 2次元に広げよう
  • 無限遠を入れ込むために(x_1,x_2)(X_1,X_2,X_3)として、x_1=\frac{X_1}{X_3},x_2 = \frac{X_2}{X_3}と斉次座標にする
  • 斉次座標の線形変換、ただそれだけ
my.projection.transform2 <- function(x,M){
	X <- c(x,1)
	X. <- M %*% X
	x. <- X./X.[length(X.)]
	x.[-length(X.)]
}
  • 射影変換を離散的な点列として扱ってきたが、変換行列の指数行列を導入すれば、連続にできる
  • 固有値が実数か複素数か、その絶対値が1か1より小か大か、というのが、連立微分方程式の解のときにも問題になるように、射影変換でも同様にそれが場合を分ける
# 指数行列
exp.m <- function(A,n){
	# 固有値分解
	eigen.out<-eigen(A)
	# P=V,P^{-1}=U
	V<-eigen.out[[2]]
	U<-solve(V)
	B<-diag(exp(eigen.out[[1]]*n))
	X <- V%*%B%*%U
	return(list(matrix = X, eigen.vs <- eigen.out[[1]]))
}
my.pr.tr.cont <- function(x,M,t=seq(from=0,to=10,length=1000)){
	X <- c(x,1)
	out <- matrix(0,length(t),length(X))
	for(i in 1:length(t)){
		tmp <- exp.m(M,t[i])
		out[i,] <- tmp[[1]] %*% X
	}
	out2 <- out/out[,length(X)]
	out2[,-length(X)]
}

x <- c(0.1,1)
theta <- runif(1)*2*pi
r <- 2
a <- cos(theta)*r
b <- sin(theta)*4
k <- 2
M <- matrix(c(a,b,0,-b,a,0,0,0,k),byrow=TRUE,3,3)

out <- my.pr.tr.cont(x,M,t=seq(from=0,to=10,length=1000))
plot(Re(out),type="l")

x <- c(0.1,1)

M <- diag(rnorm(3))

out <- my.pr.tr.cont(x,M,t=seq(from=0,to=10,length=1000))
plot(out,type="l")
  • 結局、射影変換って、「斉次座標の空間で何かしら線形に表せる形や軌道を、射影した形や軌道について考えさせてくれる」もので、なんとも不思議な動きをしていても、その背景は結構単純で、見え方の問題、とそういう意味合いとも取れる
  • 以下の例は、3次元空間でトーラス上の軌道があったときに、その射影写像

R1 <- 1
R2 <- 0.5
theta1 <- 5
theta2 <- 8
t <- seq(from=0,to=1,length=1000)*10

X <- R1*cos(theta1*t)+R2*cos(theta1*t)*cos(theta2*t)
Y <- R1*sin(theta1*t)+R2*sin(theta1*t)*cos(theta2*t)
Z <- R2*sin(theta2*t)

library(GPArotation)
M <- Random.Start(3)


library(rgl)
plot3d(X,Y,Z)

xyz <- cbind(X,Y,Z)
xyz <- t(M %*% t(xyz))
# z=0をよぎらないように…
xyz[,3] <- xyz[,3] - min(xyz[,3]) + 0.5

XY <- xyz/xyz[,length(xyz[1,])]
XY <- XY[,-length(XY[1,])]
plot(XY,type="l")