マシン・設定依存性?

  • こちらなどで、gifアニメーションを掲載している。
  • gifアニメーションは、gifファイルが、「時間差情報」とともに多数の絵を把持し、それをタイムラグつきで表示することで「ぱらぱらアニメ」として見せてくれる仕組み
  • Rでrglパッケージを用いて、3次元グラフを描き、それについて、視点を少しずつ変えながらスナップショットをとって、それをImageMagickにつなぎあわさせてgifアニメにするのが、こちらのコマンド
### 描図対象の作成部分は省略
#3次元プロット
plot3d(xx,yy,zz, col=rainbow(1000))
# 視点を変えるための行列づくり
X <- par3d("userMatrix") 
# まわしながら、スナップショットをとって、紡がせる
movie3d( par3dinterp( userMatrix=list(X,rotate3d(X, pi/2, 1, 0, 0),rotate3d(X, pi/2, 0, 1, 0) )), duration=5 ,movie="test2",dir=".")
  • 実は、Windows7でほぼ同時期に購入・設定した2台のPC(1台はDELLのデスクトップ、もう1台はパナソニックのノート)ですが、こちらの絵を描かせようとしたら、DELLデスクトップはアニメができたのに、パナノートはできず・・・
  • どこでつまずいているか、と調べると、rglパッケージのmovie3d()関数の中で、rgl.snapshot(filename = filename, fmt = "png", top = top)として、png拡張子のファイルを作らせているのですが、うまくいかない、ノートPCでは、このrgl.snapshot()で、ファイルはできるけれども、中身が真っ黒、という現象になり、そのせいで、映画も真っ黒…
  • ウェブ検索するも、同様の問題を質問している人はいたけれど、それに解決はされておらず。。。
  • ということで、友人に考えてもらったところ、pngで出すところが問題なので、psで出して、そのあと、gifアニメ化するためのフォーマット変換もImageMagickにやらせる、ということにしました
  • それで解決と思ったところ、ぱらぱらアニメの個々の絵が「透明シート」に描き出されてしまって、絵が重なって映画に見えない・・・
  • それを乗り越えるべく、ImageMagickのオプションで、ぱらぱらアニメ化のときに、表示のたびに、古い絵は消して新しいのを表示し直し、というオプション"convert -dispose previous"を付け加えて、落着。
  • ちなみに、このオプションをつけないで作った、「重ね描きジフアニメ」がこの記事に表示させてあります。
  • オプションを使えば、こちらと同じようにちゃんとした映画になります。
movie3dUneme <- function (f, duration, dev = rgl.cur(), ..., fps = 10, movie = "movie", 
    frames = movie, dir = tempdir(), convert = TRUE, clean = TRUE, 
    verbose = TRUE, top = TRUE, type = "gif", startTime = 0) 
{
    olddir <- setwd(dir)
    on.exit(setwd(olddir))
    for (i in round(startTime * fps):(duration * fps)) {
        time <- i/fps
        if (rgl.cur() != dev) 
            rgl.set(dev)
        par3d(f(time, ...))
        #filename <- sprintf("%s%03d.png", frames, i)
        filename <- sprintf("%s%03d.ps", frames, i)
        if (verbose) {
            cat("Writing", filename, "\r")
            flush.console()
        }
        #rgl.snapshot(filename = filename, fmt = "png", top = top)
        rgl.postscript(filename = filename, fmt = "ps")
    }
    cat("\n")
    if (.Platform$OS.type == "windows") 
        system <- shell
    if (is.logical(convert) && convert) {
        version <- system("convert --version", intern = TRUE)
        if (!length(grep("ImageMagick", version))) 
            stop("ImageMagick not found")
        filename <- paste(movie, ".", type, sep = "")
        if (verbose) 
            cat("Will create: ", file.path(dir, filename), "\n")
        #convert <- "convert -delay 1x%d %s*.png %s.%s"
        convert <- "convert -dispose previous -delay 1x%d %s*.ps %s.%s"
    }
    if (is.character(convert)) {
        convert <- sprintf(convert, fps, frames, movie, type, 
            duration, dir)
        if (verbose) {
            cat("Executing: ", convert, "\n")
            flush.console()
        }
        system(convert)
        if (clean) {
            if (verbose) 
                cat("Deleting frames.\n")
            for (i in 0:(duration * fps)) {
                #filename <- sprintf("%s%03d.png", frames, i)
                filename <- sprintf("%s%03d.ps", frames, i)
                unlink(filename)
            }
        }
    }
}


library(rgl)
# zの極座標用の角度パラメタ
theta<-seq(from=0,to=2*pi,length.out=100)
# zの極座標用のノルムパラメタ
r<-seq(from=0,to=1,length.out=10)
# ノルムと角度を組み合わせる
xy<-expand.grid(r,theta)
plot(xy[,1],xy[,2])
# 極座標からカルテシアンに変換
x<-xy[,1]*cos(xy[,2])
y<-xy[,1]*sin(xy[,2])
plot(x,y)

# 2値のy(ここではz1とz2)は、極座標的には、ノルムの平方根と角度が半分か、半分+piなので
# それに基づいて、二つの値を出す
z1<-sqrt(xy[,1])*cos(xy[,2]/2)
z2<-sqrt(xy[,1])*cos(xy[,2]/2+pi)
# プロットするために、定義域をタンデムに重複させ、値域は2価のそれをタンデムにつなぐ
xx<-c(x,x)
yy<-c(y,y)
zz<-c(z1,z2)
#
plot3d(xx,yy,zz, col=rainbow(1000))


X <- par3d("userMatrix") 
movie3dUneme( par3dinterp( userMatrix=list(X,rotate3d(X, pi/2, 1, 0, 0),rotate3d(X, pi/2, 0, 1, 0) )), duration=5 ,movie="test2",dir=".")