2016-05-03 5 views
5

Es wäre bequem, interaktiv einen anständigen Blickpunkt mit rgl auszuwählen und dann die gleiche Ausrichtung in einem lattice 3D-Plot anzunehmen. Zum Beispiel, wenn das folgende Diagramm einen nicht informativen Blickwinkel verwendet.Replikation eines RGL-Ansichtspunkts im Gitter

library(lattice) 
wireframe(volcano, screen = list(x=0, y=0, z=0)) 

enter image description here

Das gleiche in rgl von

library(rgl) 
persp3d(volcano) 
view3d(0, 0) 

enter image description here

interaktiv geöffnet werden kann, ist es einfach, das Grundstück zu einer informativen Ansicht zu drehen.

enter image description here

Die Matrix kann die aktuelle rgl Sicht zu geben durch

extrahiert werden
p <- par3d() 
p$userMatrix 

Wie kann diese Matrix in entsprechende x, y umgewandelt werden, zscreen Parameter die Ansicht im Gitter zu replizieren ?

UPDATE 1

versuchte ich unter 42 Bekehrung aus. Der Code zeigt das rgl-Plot und das entsprechende Gitterplot pro Zeile. Wenn ich es richtig implementiert habe (siehe Code unten), scheint immer noch ein Problem zu bestehen.

enter image description here

# convert rgl viewpoint into lattice 
# screen orientation 
rgl_to_lattice_viewpoint <- function() 
{ 
    p <- par3d() 
    rotm <- p$userMatrix 
    B = 360*atan(rotm[1,2]/rotm[2,2])/(2*pi) 
    P = 360*asin(-rotm[3,2])/(2*pi) 
    H = 360*atan(rotm[3,1]/rotm[3,3])/(2*pi) 
    list(x=-B, y=-P, z=-H) 
} 


# read and plot PNG image 
plot_png <- function(f) 
{ 
    img <- readPNG(f) 
    rimg <- as.raster(img)  # raster multilayer object 
    plot(NULL, xlim=c(0,1), ylim=c(0,1), xlab = "", ylab = "", 
     asp=1, frame=F, xaxt="n", yaxt="n") 
    rasterImage(rimg, 0, 0, 1, 1) 
} 


# create rgl snapshot with random rotation and 
# corresponding lattice wireframe plot 
lattice_plus_rgl_plot <- function() 
{ 
    # rgl plot random rotation 
    persp3d(volcano, col = "green3") 
    theta <- sample(-180:180, 1) 
    phi <- sample(-90:90, 1) 
    view3d(theta, phi, fov=40) 
    v <- rgl_to_lattice_viewpoint() 
    f <- tempfile(fileext = ".png") 
    rgl.snapshot(f) 
    rgl.close() 

    # lattice plot 
    f2 <- tempfile(fileext = ".png") 
    png(f2) 
    print(wireframe(volcano, screen = v)) 
    dev.off() 

    # plot both 
    plot_png(f) 
    plot_png(f2) 
} 

# CREATE SOME PLOTS 

library(rgl) 
library(lattice) 
library(png) 
par(mfrow=c(3,2), mar=c(0,0,0,0)) 
replicate(3, lattice_plus_rgl_plot()) 

Antwort

1

benutzte ich die Antwort auf diese Frage für die Umwandlung von einer Rotationsmatrix zu Winkel: Conversion euler to matrix and matrix to euler. Ich gebe zu Bedenken, dass ich hier eine andere etwas andere Antwort sehe: How to calculate the angle from Roational matrix. (Meine lineare Algebra ist nicht gut genug, um zu bestimmen, welche diesen korrekt ist.)

p <- par3d() 
rotm <- p$userMatrix 
B = 360*atan(rotm[1,2]/rotm[2,2])/(2*pi) 
P = 360*asin(-rotm[3,2])/(2*pi) 
H = 360*atan(rotm[3,1]/rotm[3,3])/(2*pi) 

> print(list(B,P,H)) 
[[1]] 
[1] 41.54071 

[[2]] 
[1] 40.28412 

[[3]] 
[1] 41.24902 

An diesem Punkt hatte ich gedreht bereits das RGL-Objekt in etwa dem „Blickpunkt“, die Sie vorgeschlagen hatten. Ich habe durch Experimente herausgefunden, dass die negativen Werte, die dem Drahtgitteraufruf zugeführt wurden, scheinbar korrekte Ergebnisse geliefert haben. "Betrachterdrehwinkel" werden plausibel als das Negativ für "Objektdrehwinkel" gesehen.

png(); print(wireframe(volcano, screen = list(x=-B, y=-P, z=-H))); dev.off() 

enter image description here

Es gibt eine rotate.wireframe Funktion im Paket TeachingDemos aber es spielt nicht gut mit gleichzeitig laufenden rgl Plots. (Keine Handlung war offensichtlich, bis ich das rgl-Gerät schloss.) Es schien auch irgendwie fehlerhaft, wenn es auf einem Mac lief (dicke schwarze Linie über dem Gitterplot). Es verwendet die X11/XQuartz-Funktionen, um die Interaktion über tk/tcl-Funktionen zu verwalten, und ich konnte die Plots nicht aus den angezeigten Winkeln reproduzieren. Mit Blick auf den Code kann ich nicht verstehen, warum das so sein sollte. Aber Ihre Laufleistung kann variieren.

+0

Danke! :) Ich habe meinen Beitrag bearbeitet (UPDATE 1), wo ich die von dir vorgeschlagene Konvertierung ausprobiert habe. Es scheint ein Problem zu bestehen, da ich keinen Fehler gemacht habe. –

1

Diese Version Ihrer Funktion verwendet Konvertierungen aus dem orientlib Paket und macht die Rotationsmatrix ein Argument:

rgl_to_lattice_viewpoint <- function(rotm = par3d("userMatrix")) 
{ 
    e <- -orientlib::eulerzyx(orientlib::rotmatrix(rotm[1:3, 1:3]))@x*180/pi 
    list(z = e[1], y = e[2], x = e[3]) 
} 

Beachten Sie, dass die z, y, x wesentlich ist.

es in einem Ort Ihrer Funktion verwenden, erhalte ich diese Ausgabe: rgl and lattice plots

Diese die Rotation richtig. Ich weiß nicht, ob es auch möglich ist, die passende Perspektive zu finden.

Bearbeitet zu hinzufügen: rgl Version 0.95.1468, bisher nur auf R-Schmiede, enthält eine Version dieser Funktion und eine für die Basis-Grafiken.