- Moving frameを回転する回転行列とフルネ=セレの行列の関係を考える
- フレネ=セレの行列は
- 一方、Moving frameを回転させる行列は
- ここで、回転行列を特異値に分解しとすると
- となる
- を十分小さくすれば、回転行列の処理を繰り返しても曲線が描ける
- このような行列は次のようにして作る
- 第i曲率をとしたときに、そのサインとコサインをそれぞれとする
- のとき
- のとき
- のとき
- Rで確かめてみよう
n<-5
Ksin<-runif(n-1)
MakeFrenetSerret<-function(K){
n<-length(K)+1
M<-matrix(0,n,n)
for(i in 1:length(Ksin)){
M[i,i+1]<--Ksin[i]
M[i+1,i]<-Ksin[i]
}
M
}
M<-MakeFrenetSerret(Ksin)
E.outK<-eigen(M)
VK<-E.outK[[2]]
V2K<-solve(VK)
SK<-diag(E.outK[[1]])
MakeMatRotatingMF<-function(K){
Ksin<-K
Kt<-asin(Ksin)
Kcos<-cos(Kt)
Mk<-matrix(0,n,n)
Mk[1,1]<-Kcos[1]
Mk[1,2]<--Ksin[1]
for(i in 2:n){
Mk[i,1:(i-1)]<-Mk[i-1,1:(i-1)]*Ksin[i-1]/Kcos[i-1]
Mk[i,i]<-Kcos[i-1]
if(i<n){
Mk[i,1:i]<-Mk[i,1:i]*Kcos[i]
Mk[i,i+1]<--Ksin[i]
}
}
Mk
}
Diff<-MakeMatRotatingMF(Ksin)
E.out<-eigen(Diff)
V<-E.out[[2]]
V2<-solve(V)
S<-diag(E.out[[1]])
Niter<-1000
dt<-0.001
xs<-matrix(0,Niter,n)
xs[1,]<-runif(n)
xsK<-xs
T<-runif(Niter-1)
dhk<-NormalBase(n)
dhkK<-dhk
v<-dhk[1,]
vK<-dhkK[1,]
for(i in 2:Niter){
xs[i,]<-xs[i-1,]+v*dt
xsK[i,]<-xsK[i-1,]+vK*dt
dhk<-(V%*%diag(E.out[[1]]^(dt))%*%V2) %*% dhk
dhkK<-M%*%dhkK*dt+ dhkK
ll<-apply(dhk^2,1,sum)
dhk<-((dhk)/sqrt(ll))
v<-dhk[1,]
llK<-apply(dhkK^2,1,sum)
dhkK<-((dhkK)/sqrt(llK))
vK<-dhkK[1,]
}
library(rgl)
plot3d(xs[,1],xs[,2],xs[,3],col=rainbow(Niter),main="Moving Frame Rotating Matrix")
open3d()
plot3d(xsK[,1],xsK[,2],xsK[,3],col=rainbow(Niter),main="Frenet-Serret")
open3d()
plot3d(c(xs[,1],xsK[,1]),c(xs[,2],xsK[,2]),c(xs[,3],xsK[,3]),col=c(rep(1,Niter),rep(2,Niter)),main="Black=Rotation,Red=Frenet-Serret")
- 本当は、回転行列があって、その回転のs微分がに一致するように回転行列を作ればよいのかと思うのだが…
- 以下はその試行錯誤(で、まだ成功していない)
- フレネ=セレの行列は
- 一方、Moving frameを回転させる行列は
- ここで、回転行列を特異値に分解しとすると
- となる
- は対角行列で、その成分である
- を対角成分とする行列をとし
- とする
- なので
- を特異値分解しを求め
- の対角成分を満足するようにする
- は対角行列で、その成分である
- 1からn-1次の曲率を与える
- という関係(第i番目のmoving frame ベクトルの時間変化との第i+1番目のmoving frameベクトルとの内積が第i番目の曲率)であるから…
- 以下のソースは動くけれど、思ったようには動いていない。
Ksin<-runif(n-1)
MakeFrenetSerret<-function(K){
n<-length(K)+1
M<-matrix(0,n,n)
for(i in 1:length(Ksin)){
M[i,i+1]<--Ksin[i]
M[i+1,i]<-Ksin[i]
}
M
}
M<-MakeFrenetSerret(Ksin)
E.outK<-eigen(M)
VK<-E.outK[[2]]
V2K<-solve(VK)
SK<-diag(E.outK[[1]])
Kt<-asin(Ksin)
Kcos<-cos(Kt)
Mk<-matrix(0,n,n)
Mk[1,1]<-Kcos[1]
Mk[1,2]<--Ksin[1]
for(i in 2:n){
Mk[i,1:(i-1)]<-Mk[i-1,1:(i-1)]*Ksin[i-1]/Kcos[i-1]
Mk[i,i]<-Kcos[i-1]
if(i<n){
Mk[i,1:i]<-Mk[i,1:i]*Kcos[i]
Mk[i,i+1]<--Ksin[i]
}
}
Diff<-M
t(Diff)%*%Diff
E.out<-eigen(Diff)
V<-E.out[[2]]
V2<-solve(V)
S<-diag(E.out[[1]])
Reals<-Re(E.out[[1]])
Imags<-Im(E.out[[1]])
Ar<-Arg(E.out[[1]])
Mods<-Mod(E.out[[1]])
RotsS<-diag(complex(real=cos(Mods),imaginary=sin(Mods)))
Rot<-V%*%RotsS%*%V2
Niter<-1000
xs<-matrix(0,Niter,n)
xs[1,]<-runif(n)
xsK<-xs
dt<-0.01
T<-runif(Niter-1)
dhk<-NormalBase(n)
v<-dhk[1,]
dhkK<-dhk
vK<-dhkK[1,]
for(i in 2:Niter){
xs[i,]<-(V%*%diag(E.out[[1]]^(dt*(i-1)))%*%V2)%*%xs[1,]
xsK[i,]<-xsK[i-1,]+vK*dt
dhk<-(V%*%RotsS^(dt)%*%V2) %*% dhk
dhk<-Re(dhk)
dhkK<-M%*%dhkK*dt+ dhkK
ll<-apply(dhk^2,1,sum)
dhk<-((dhk)/sqrt(ll))
v<-dhk[1,]
llK<-apply(dhkK^2,1,sum)
dhkK<-((dhkK)/sqrt(llK))
vK<-dhkK[1,]
print(v)
print(vK)
print("---")
}
library(rgl)
plot3d(xs[,1],xs[,2],xs[,3],col=rainbow(Niter))
open3d()
plot3d(xsK[,1],xsK[,2],xsK[,3],col=rainbow(Niter))
open3d()
plot3d(c(xs[,1],xsK[,1]),c(xs[,2],xsK[,2]),c(xs[,3],xsK[,3]),col=c(rep(1,Niter),rep(2,Niter)))
matplot(xs,type="l")