矯めつ眇めつ

  • 分子立体構造を見るためのアプリを教えてもらった(こちら)

http://www.rcsb.org/pdb/general_information/news_publications/newsletters/2012q4/images/viewer.png

  • 3次元オブジェクトを2次元感覚器(視覚器)を介して理解するのを補助するアプリ。『矯めつ眇めつ』眺めるために、2次元平面への像の取り方を変えることを通じて3次元オブジェクトを理解するためには、像の取り方を自在に変えられることが大事だ、という精神を具現化するもの。
  • アプリを使ってもよいし、使わなくてもよいけれど、『矯めつ眇めつ』するときって、どういう風に像の取り方を変えているだろう?
  • まず、大雑把に『全体(と思われるもの)』を眺めて(そうするのに適当な作像ルールで2次元画像の列を作成する)
  • その次に、2次元画像列から、意味の大きな画像変化部分に注目する
  • 注目したら、その画像変化部分について、画像列の刻みを細かくする
  • 注目したら、その画像変化部分について、すでに見た画像列とは違う方向(画像列は1次元なので、3次元オブジェクトの表面である2次元多様体については、別方向がある)について情報をとる
  • それらを通じて、結局、3次元オブジェクトの表面である2次元多様体(これは閉じている)の表面に、メッシュ構造(これが像の作り方に対応する)を作って、そのメッシュ構造に関する情報と、メッシュ構造上の点ごとに作成した2次元画像との情報とを『総合』して『2次元視覚』による『3次元オブジェクトの表面』に関する理解に達する
  • 3次元オブジェクトの2次元視覚観察で、『あれっ』と思いがちなのは、ドーナツのようなもの
  • どうしてドーナツが『あれっ』なのかというと、「デフォルト」の観察は、トポロジー的に「球体」を「想定」し、そことの比較としてメッシュと画像の束を処理するように頭ができているからか?
  • さて、n次元オブジェクトの表面であるn-1次元多様体をn-1次元視覚機能で「理解」する、というときにはどうしたらよいのか
  • 簡単なのは、n次元のオブジェクトとしてトポロジー的に「球体」なもの。そこからの逸脱は場合分けがすごいことになりそうだが、さて…。
  • 3次元のオブジェクトは2次元視覚で観察すると、「2次元の形」が「2次元的な動き」に応じて変化する。
  • n次元のオブジェクトはn-1次元視覚で観察すると、「n-1次元の形」が「n-1次元的な動き」に応じて変化する
  • n-1次元視覚はn-1次元的な動きを理解することができる。なぜなら、次元がn-1次元に納まっているから。理解しないといけないのは「変化」することと、その「変化」とは、n-1次元で理解するのではなくて、次元を一つ増やすことで理解する方法がある、ということ
  • 生物の情報処理的には、空間の次元を増やす方便として時間がもつ1つの次元を使っている。だからn-1次元視覚を用いてn次元オブジェクトが理解できる
  • 時間が2次元だったら、n-1次元視覚を用いて(n-1)+2=n+1次元オブジェクトも理解できるかもしれない
  • 「変化」するものの理解は、「パターン」認識。「こういう変化パターン」はn次元オブジェクトとして、こういうものだ、となっている、と言う理解。それを支えるのは、触覚(など)がつかさどるn次元感覚。「丸い」とか「尖っている」とか。

矯めつ眇めつ2

  • n次元オブジェクトをn-1次元視覚で矯めつ眇めつするのには、オブジェクト周囲に適当に視点を取ってやるのが良さそうだ。そのうえで、視点と近傍視点との間に「差分」を取って、視点間n-1次元像の違いが「気になる」ところを「着目すべき辺」とする、というような手続きがよさそうだ
  • そうするためには、n次元に凸包(convex hull)を取りたい
  • Rだとgeometry パッケージのconvhulln()関数とか、dlaunayn()関数(ドロネー図)とか
install.packages("geometry")
library(geometry)

n.pt <- 100

d <- 3

X <- matrix(rnorm(n.pt*d),ncol=d)
X <- X/sqrt(apply(X^2,1,sum))
apply(X^2,1,sum)

tried <- delaunayn(X)

library(rgl)
plot3d(X)

segs <- matrix(NA,nrow=0,ncol=d)
ex.gr <- expand.grid(1:d,1:d)
for(i in 1:length(tried[,1])){
	for(j in 1:length(ex.gr[,1])){
		if(ex.gr[j,1]!=ex.gr[j,2]){
			segs <- rbind(segs,X[c(tried[i,ex.gr[j,1]],tried[i,ex.gr[j,2]]),])
		}
	}
}

plot3d(X[,1:3])
segments3d(segs[,1:3])

tried.2 <- t(convhulln(X))

rgl.triangles(X[tried.2,1],X[tried.2,2],X[tried.2,3],col="red",alpha=.2)
for(i in 1:(8*360)) rgl.viewpoint(i/8)
  • 球面上に適当に乱点を発生させて、そこに凸包を作って、その後で、少し調整して比較的均整のとれた凸包にしてみる、とか
n.pt <- 40
d <- 3

X <- matrix(rnorm(n.pt*d),ncol=d)
X <- X/sqrt(apply(X^2,1,sum))
apply(X^2,1,sum)

xyz <- X


tried.2 <- t(convhulln(xyz))
tried.2.v <- c(tried.2)
tried.2.u <- unique(tried.2.v)

plot3d(xyz[tried.2.u,])

rgl.triangles(xyz[tried.2,1],xyz[tried.2,2],xyz[tried.2,3],col="red",alpha=.2)
for(i in 1:(8*360)) rgl.viewpoint(i/8)


length(tried.2.v)
length(tried.2.u)
m <- matrix(0,length(tried.2.u),length(tried.2.u))

for(i in 1:length(tried.2[1,])){
	for(j in 1:(length(tried.2[,1])-1)){
		v1 <- tried.2[j,i]
		V1 <- which(tried.2.u==v1)
		for(j2 in (j+1):length(tried.2[,1])){
			v2 <- tried.2[j2,i]
			V2 <- which(tried.2.u==v2)
			m[V1,V2] <- 1
			m[V2,V1] <- 1
		}
	}
}

n.iter <- 1000

xyz.2 <- xyz
s <- sample(1:length(tried.2.u),n.iter,replace=TRUE)
for(i in 1:n.iter){
	tmp.s <- s[i]
	tmp.neighbor <- which(m[tmp.s,]==1)
	tmp.xyz <- xyz.2[tried.2.u[tmp.neighbor],]
	tmp.m <- apply(tmp.xyz,2,mean)
	tmp.m <- tmp.m/sqrt(sum(tmp.m^2))
	xyz.2[tried.2.u[tmp.s],] <- tmp.m
}
open3d()
plot3d(xyz.2[tried.2.u,])
rgl.triangles(xyz.2[tried.2,1],xyz.2[tried.2,2],xyz.2[tried.2,3],col="red",alpha=.2)