- 昨日はDNA二重らせんを描いてみた
- 3次元空間におけるらせんについて少し考えてみる
- 結果としてこんな絵ができる
- DNAは2重らせんを作った上で、さらに高次構造を作っている。ヒストンとのタンパク複合体を作ったり、とその現実界的折りたたみ構造についてわかっていることは多いが、さて一般に、ひも状のものをくるくると畳むにはどうすればよいのか、という点に照らして考えてみる
- そもそも、(2重)らせんの「らせん」が「まっすぐに伸ばせは長いひも」をくるくる巻きにすることで、「線の太さ」はくるくる直径分に長くなるけれど、長く伸びたひもっぽい長さを短くする、という仕組みになっている
- これを一般化しよう
- まず普通のらせんを「1次のらせん」と呼ぶことにして、「高次化」への準備をする
- 「1次のらせん」を円だけで表現する
- 昨日の記事でも書いたように、1次のらせんは、xy平面に円を描きながら、z方向に等速で移動したときに描かれる軌跡である
- ここには、「円」と「直線」という2種類の動きが出てくる
- 「高次化したらせん」では、らせん軌道を進みながら、その軌道上の点を中心として円を描かせたい
- そのようなとき「直線」を進みながら「周回円」を描くという「1次のらせん」ではなく、「円的な部分を持った曲線」を進みながら「周回円」を描きたい
- したがって「1次のらせん」で登場する「直線」を「円」的なものとして表すことにしよう
- 直線は半径が無限大の円弧であると考えれば、直線は円として表現できる
- このようにすることで、登場するすべての動きを「円」としてしまう算段がついた
- 「1次のらせん」とトーラスの関係
- 「1次のらせん」を円弧に沿って進みながら、その円弧の垂直断面に円を描くと、それは、円の組合せであって、いわゆるトーラス上の軌道になる
- 「いわゆるトーラス」上の軌道
- トーラス上の軌道は
- と表すことができる。ここでは第1、第2の円の半径であり、は第1、第2の円の周回の速度を決めるパラメタである
- 「いわゆるトーラス」上の軌道を表現の見通しを良くする
- 第1の円
- 第1の円は、原点を中心に、ある1点をスタート点とした円である
- そのような円の上の点をとし、原点をとする
- このとき、この点は、ベクトルに垂直な進行方向ベクトルがある
- ここで、2つのベクトルととに垂直なベクトルを、この2ベクトルの外積ベクトルとしてとりそれをと置くことにしよう
- 第2の円
- 第2の円はを中心とし、ととが張る平面上の円である
- このような第2の円について、半径角だけ回った点は、xy平面上でのそのような点を、という座標軸をという座標軸(ただしはベクトルを単位ベクトル化したもの)に回転したものと考えればよい
- 結局、上記の処理は、ある回転運動aをしている点を中心に回転bしているときの点を、存在位置座標と、そこでの回転aの法線ベクトルと回転方向ベクトルとから、その外積ベクトルを介して回転bによる座標の変化分を加える、という読み方にしたものである
- これは、第1の円、その上の第2の円、さらにその上の第3の円…と積み重ねることが容易な表現になっている
- 以下はこれをRで実装したもの
- 周期がの整数倍だと、軌道は「元に戻る」ので、曲線が次のように閉じる
library(rgl)
ori <- c(0,0,0)
Rs <- 1.3^(10:1)
Ts <- 2^(1:10)
n.steps <- length(Rs)
max.t <- 4
t.n <- 10000
t <- seq(from=0,to=max.t,length=t.n)
unit.vector <- function(X){
v <- sqrt(apply(X^2,1,sum))
X/v
}
outer.prod <- function(v1,v2){
c(v1[2]*v2[3]-v1[3]*v2[2],v1[3]*v2[1]-v1[1]*v2[3],v1[1]*v2[2]-v1[2]*v2[3])
}
outer.prod.V <- function(V1,V2){
cbind(V1[,2]*V2[,3]-V1[,3]*V2[,2],V1[,3]*V2[,1]-V1[,1]*V2[,3],V1[,1]*V2[,2]-V1[,2]*V2[,1])
}
X <- list()
V <- list()
X[[1]] <- V[[1]] <- cbind(rep(0,t.n),rep(0,t.n),rep(0,t.n))
X[[2]] <- cbind(Rs[1]*cos(Ts[1]*t),Rs[1]*sin(Ts[1]*t),rep(0,t.n))
V[[2]] <- cbind(-Rs[1]*sin(Ts[1]*t),Rs[1]*cos(Ts[1]*t),rep(0,t.n))
for(i in 2:n.steps){
tmp.x <- X[[i]]-X[[i-1]]
tmp.x <- unit.vector(tmp.x)
tmp.v <- unit.vector(V[[i]])
tmp.z <- outer.prod.V(tmp.x,tmp.v)
tmp.X <- cbind(Rs[i]*cos(Ts[i]*t),Rs[i]*sin(Ts[i]*t),rep(0,t.n))
V[[i+1]] <- cbind(-Rs[i]*sin(Ts[i]*t),Rs[i]*cos(Ts[i]*t),rep(0,t.n))
for(j in 1:t.n){
tmp.X[j,] <- cbind(tmp.x[j,],tmp.z[j,],tmp.v[j,]) %*% tmp.X[j,]
V[[i+1]][j,] <- cbind(tmp.x[j,],tmp.z[j,],tmp.v[j,]) %*% V[[i+1]][j,]
}
X[[i+1]] <- X[[i]] + tmp.X
}
plot3d.minmax <- function(X){
min.X <- min(X)
max.X <- max(X)
tmp <- rbind(X,rep(min.X,length(X[1,])),rep(max.X,length(X[1,])))
plot3d(tmp,col="white",axes=FALSE)
}
tmp.d <- dist(X[[n.steps+1]])
max.X <- max(X[[n.steps+1]])
min.X <- min(X[[n.steps+1]])
dd <- max.X-min.X
plot3d.minmax(X[[n.steps+1]])
spheres3d(X[[n.steps+1]],col=2,radius=max(min(tmp.d)*0.5,dd*0.001))
s <- rep(1:t.n,each=2)
s <- s[2:(length(s)-1)]
segments3d(X[[n.steps+1]][s,])