Ist es möglich, Graphics3D
in einem isometrische Projektion ? Ich weiß, dass die Option ViewPoint
für die orthogonale Projektion verwendet werden kann, indem z. ViewPoint -> {0, Infinity, 0}
. Dies erfordert jedoch nicht mehrere Unendlichkeiten, sodass ich beispielsweise ViewPoint -> {Infinity, -Infinity, Infinity}
nicht ausführen kann.
Mir ist klar, dass ich dies durch Drehen der gesamten Szene erreichen kann ungefähr zwei Achsen und unter Verwendung einer orthogonalen Projektion:
Graphics3D[ Rotate[ Rotate[ Cuboid[{-.5, -.5, -.5}], Pi/4, {0, 0, 1} ], ArcTan[1/Sqrt[2]], {0, 1, 0} ], ViewPoint -> {-Infinity, 0, 0} ]
Dies ist jedoch ziemlich umständlich und es ist „schwieriger, die richtigen Rotationen für den Ansichtspunkt I herauszufinden“. Ich bin eher daran interessiert. Ich würde lieber nur den Oktanten angeben, von dem aus die Szene isometrisch betrachtet werden soll. Gibt es tatsächlich einen „richtigen“ Weg, um dies zu erreichen?
Kommentare
- Ich habe hier eine isometrische Projektion durchgeführt: mathematica.stackexchange.com/questions/28000/isometric-3d-plot/… .
- @ MichaelE2 Oh, okay, ich habe nur den Fragentext gelesen und ' nicht gesehen, was es mit isometrischem Plotten zu tun hat (sollte habe auch die Kommentare gelesen). Aber ich denke, Ihr Ansatz ist meinem ähnlich, außer dass die Verwendung von zwei Vektoren für die Rotation offensichtlich ist Dies ist einfacher als die Verwendung von zwei Winkeln.
Antwort
Ab V11.2 können wir eine Kombination von ViewProjection
und ViewPoint
:
Graphics3D[Cuboid[], ViewProjection -> "Orthographic", ViewPoint -> {1, 1, 1}]
Verschiedene Vorteile:
v = Tuples[{Tuples[{-1, 1}, 3], IdentityMatrix[3]}]; Graphics3D[Cuboid[{-.5, -.5, -.5}, {1., 2., 4}], ViewProjection -> "Orthographic", ViewPoint -> #1, ViewVertical -> #2] & @@@ v
Antwort
[Hinweis bearbeiten: Aktualisiert, um die vertikale Richtung des Diagramms festzulegen und einen Fehler zu beheben .]
Hier ist eine leichte Verallgemeinerung meiner Antwort auf Isometrisches 3D-Diagramm . Um eine isometrische Ansicht zu erhalten, müssen wir eine ViewMatrix
erstellen, die einen Vektor der Form {±1, ±1, ±1}
bis {0, 0, 1}
und orthogonal auf die ersten beiden Koordinaten projizieren.
ClearAll[isometricView]; isometricView[ g_Graphics3D, (* needed only for PlotRange *) v_ /; Equal @@ Abs[N@v] && 1. + v[[1]] != 1., (* view point {±1, ±1, ±1} *) vert_: {0, 0, 1}] := (* like ViewVertical; default: z-axis *) {TransformationMatrix[ RescalingTransform[ EuclideanDistance @@ Transpose[Charting`get3DPlotRange@ g] {{-1/2, 1/2}, {-1/2, 1/2}, {-1/2, 1/2}}]. RotationTransform[{-v, {0, 0, 1}}]. RotationTransform[{vert - Projection[vert, v], {0, 0, 1} - Projection[{0, 0, 1}, v]}]. RotationTransform[Mod[ArcTan @@ Most[v], Pi], v]. TranslationTransform[-Mean /@ (Charting`get3DPlotRange@ g)]], {{0, 1, 0, 0}, {1, 0, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}}; foo = Graphics3D[Cuboid[{-.5, -.5, -.5}, {1., 2., 4}]]; Show[foo, ViewMatrix -> isometricView[foo, {1, 1, 1}, {0, 0, 1}], ImagePadding -> 20, Axes -> True, AxesLabel -> {x, y, z}] Show[foo, ViewMatrix -> isometricView[foo, {-1, 1, 1}, {1, 1, 0}], ImagePadding -> 20, Axes -> True, AxesLabel -> {x, y, z}]
Alle Kombinationen von Blickwinkeln und vertikalen Achsen:
inweise:
Für die Berechnung ist es wichtig, einen genauen Plotbereich zu erhalten, der die Auffüllung enthält die richtige Ansichtsmatrix. Es gibt Alternativen zur undokumentierten internen Funktion Charting`get3DPlotRange
. Alexey Popkov hat hier eine Methode: Wie erhalte ich den absoluten PlotRange mit AbsoluteOptions? Ich habe PlotRange /. AbsolutOptions[g, PlotRange]
verwendet und mit 1.02
(Ich kann mich nicht erinnern, warum nicht so etwas wie 1.04
), um die Auffüllung in meiner Antwort auf Isometrisches 3D-Diagramm .
Meine Anlaufstelle zum Verständnis von ViewMatrix
war insbesondere Heikes Antwort auf Werte für ViewMatrix aus einer Graphics3D extrahieren .
Dieses Update ist eine Reaktion auf Yves „ Kommentar. Durch die Arbeit mit den Achsen wurde mir klar, dass das Koordinatensystem umgedreht ist (von „rechtshändig“ zu „linkshändig“). Daher habe ich die Projektion von IdentityMatrix[4]
in eine geändert, die die x & y-Koordinaten umdreht.
Es könnte a sein Gute Idee, Deploy
die Grafiken zu verwenden, um eine Drehung mit der Maus zu verhindern. Wenn die Grafiken gedreht werden, setzt das Frontend die ViewMatrix
auf ziemlich hässliche Weise zurück.
Kommentare
- Sehr schön – ist es möglich, die Z-Achse vertikal auszurichten?
- @YvesKlett Das war etwas schwieriger als ich dachte, hauptsächlich weil ich etwas falsch verstanden hatte.
- Super! Dies wird nützlich sein!
Antwort
Sie können den folgenden Beitrag verwenden -Prozessfunktion zum Anwenden einer allgemeinen Parallelprojektion:
parallelProjection[g_Graphics3D, axes_, pad_: 0.15] := Module[{pr3, pr2, ar, t}, pr3 = {-pad, pad} (#2 - #) & @@@ # + # &@Charting`get3DPlotRange@g; pr2 = MinMax /@ Transpose[[email protected]]; ar = Divide @@ Subtract @@@ pr2; t = AffineTransform@Append[Transpose@axes, {0, 0, -1}]; t = RescalingTransform@Append[pr2, pr3[[3]]].t; Show[g, AspectRatio -> 1/ar, ViewMatrix -> {TransformationMatrix[t], IdentityMatrix[4]}]];
Hier definiert axes
die Projektion von x, y, z-Achsen in die 2D-Ebene und pad
bietet Platz für die Anzeige von Achsenbeschriftungen.
Isometrische Projektion:
g = Graphics3D[Cuboid[], Axes -> True, AxesLabel -> {X, Y, Z}]; parallelProjection[g, {{-Sqrt[3]/2, -1/2}, {Sqrt[3]/2, -1/2}, {0, 1}}]
Schrankprojektion:
α = π/4; parallelProjection[g, {{1, 0}, {0, 1}, -{Cos[α]/2, Sin[α]/2}}]
Antwort
Nur für den Fall, dass Sie nicht nach einer vollständig korrekten Lösung suchen, sondern nur nach einer billigen Problemumgehung.
Ich suchte nach einer ViewPoint->{Infinity,Infinity, Infinity}
Lösung. Durch Ersetzen von Infinity durch eine Zahl, die groß genug ist (in meinem Fall 500), konnte ich die gewünschten Ergebnisse erzielen.