2016-04-23 19 views
2

Was ich erreichen möchte ist, ein 3D-Diagramm in rgl, drehen Sie es in die Ansicht, die ich zeigen möchte, und speichern Sie es dann in eine Datei. Ich weiß, dass ich dies mit der rgl.snapshot Funktion wie folgt tun:Speichern Sie ein rgl 3D Scatterplot in einem verlustfreien Format wie Svg oder pdf

library(rgl) 

x <- runif(20) 
y <- runif(20) 
z <- runif(20) 
plot3d(x, y, z) 
rgl.snapshot("rgl.snapshot.png") 

Das Problem ist, dass rgl.snapshot erzeugt eine Datei in der Bildschirmauflösung, daher keine hohe Auflösung genug für den Druck. Ich habe keine Möglichkeit, die Auflösung zu beeinflussen, in der die Datei gespeichert wird. Im Allgemeinen wäre es sogar noch besser, wenn ich die Datei in einem Vektorformat wie PDF oder SVG speichern könnte.

Meine Idee war es, die Rotation der aktuellen Ansicht zu speichern und sie mit einer anderen Funktion zu verwenden, die ein nicht interaktives 3D-Streudiagramm wie scatter3D aus dem plot3D-Paket erzeugt. Um die Rotationsmatrix zu speichern tat ich folgendes:

rotationMatrix <- rgl.projection() 

Sie können es auch tun, wie folgt:

rotationMatrix <- par3d()$modelMatrix 

Die Rotationsmatrix wie folgt aussieht:

$model 
      [,1]  [,2]  [,3]  [,4] 
[1,] 0.9584099 0.0000000 0.0000000 -0.4726846 
[2,] 0.0000000 0.3436644 0.9792327 -0.6819317 
[3,] 0.0000000 -0.9442102 0.3564116 -3.6946754 
[4,] 0.0000000 0.0000000 0.0000000 1.0000000 

$proj 
     [,1]  [,2]  [,3]  [,4] 
[1,] 3.732051 0.000000 0.000000 0.00000 
[2,] 0.000000 3.732051 0.000000 0.00000 
[3,] 0.000000 0.000000 -3.863703 -14.36357 
[4,] 0.000000 0.000000 -1.000000 0.00000 

$view 
    x  y width height 
    0  0 256 256 

Jetzt ist meine Frage wie komme ich von dieser Rotationsmatrix zu den Argumenten phi und theta, die von der scatter3D Funktion verwendet werden.

library(plot3D) 

# phi = ? 
# theta = ? 
pdf("scatter3D.pdf") 
scatter3D(x, y, z, pch=20, phi = 20, theta =30, col="black") 
dev.off() 

Ich weiß, es gibt Mathe, um einen Rotationswinkel aus einer Rotationsmatrix zu extrahieren. Ich weiß nicht, wie ich es in meinem Fall anwenden soll. Zumal die Matrix 4 Zeilen und Spalten hat. Ich würde 3 von jedem erwarten ... Das nächste Problem ist, dass scatter3D nur zwei Drehachsen verwendet (Theta gibt die Azimutalrichtung und phi die Colatitude an), also müsste ich von einer 3-Achsen-Rotation in die gleiche Rotation umwandeln, die sich aus a ergibt zweiachsige Drehung. Ich denke, die Rotationsachse von Phi ist durch die Rotation von Theta definiert.

Wenn es eine andere Möglichkeit gibt, einen rgl Schnappschuss in einem verlustfreien Format zu speichern, würde ich mich freuen darüber zu erfahren!

+1

Sie können die Auflösung eines Schnappschusses ändern, indem Sie die Größe des ursprünglichen rgl-Fensters ändern. Sie sind auf die Bildschirmgröße beschränkt, daher ist dies möglicherweise nicht ausreichend. Sie können rgl.postscript manchmal für ein Vektorformat verwenden, aber es behandelt nicht alle Szenen richtig. – user2554330

+0

Arrg, ja, das ist es. Für mich geht das. Ich habe gerade nicht bemerkt, dass diese Funktion bereits im Paket vorhanden ist. – nnn

Antwort

1

Die letzte Version (nur R-forge; siehe How do I install the latest version of rgl? für wie man es bekommt) Version von rgl hat eine Funktion rglToBase(), die die phi und theta Werte zurückgibt, die Sie benötigen. Es gibt auch rgl.postscript() wie in meinem Kommentar vom 24. April erwähnt, der in einem verlustfreien Format speichert (aber nicht alles speichern kann).

Bearbeitet hinzufügen: Eine sehr neue Ergänzung ist die writeASY() Funktion. Dies schreibt den Asymptote-Quellcode aus, um das Bild in verschiedenen Formaten, hauptsächlich für LaTeX-Dokumente, zu zeichnen. Siehe http://asymptote.sourceforge.net. Dies ist immer noch ein wenig begrenzt (Subszenen werden nicht unterstützt, Oberflächenbeleuchtung ist nicht perfekt, etc.), aber es ist da. Vorschläge wären willkommen.