È possibile eseguire il rendering di Graphics3D
in un proiezione isometrica ? So che lopzione ViewPoint
può essere utilizzata per la proiezione ortogonale specificando, ad es. ViewPoint -> {0, Infinity, 0}
. Tuttavia, questo non richiede più infiniti, quindi non posso “fare ViewPoint -> {Infinity, -Infinity, Infinity}
, ad esempio.
Mi rendo conto che potrei ottenere questo risultato ruotando lintera scena circa due assi e utilizzando una proiezione ortogonale:
Graphics3D[ Rotate[ Rotate[ Cuboid[{-.5, -.5, -.5}], Pi/4, {0, 0, 1} ], ArcTan[1/Sqrt[2]], {0, 1, 0} ], ViewPoint -> {-Infinity, 0, 0} ]
Tuttavia, questo è piuttosto macchinoso ed è più difficile capire le rotazioni corrette per il punto di vista I ” Sono interessato. Preferirei semplicemente specificare lottante da cui visualizzare la scena in modo isometrico. Esiste effettivamente un modo “appropriato” per ottenere questo risultato?
Commenti
- Ho eseguito una proiezione isometrica qui: matematica.stackexchange.com/questions/28000/isometric-3d-plot/… .
- @ MichaelE2 Oh, okay, ho letto solo il corpo della domanda e ' non ho visto cosa aveva a che fare con la stampa isometrica (dovrebbe ho letto anche i commenti). Ma immagino che il tuo approccio sia simile al mio, tranne che luso di due vettori per la rotazione è ovvio iously più semplice che usare due angoli.
Risposta
A partire dalla V11.2 possiamo usare una combinazione di ViewProjection
e ViewPoint
:
Graphics3D[Cuboid[], ViewProjection -> "Orthographic", ViewPoint -> {1, 1, 1}]
Vari vantaggi:
v = Tuples[{Tuples[{-1, 1}, 3], IdentityMatrix[3]}]; Graphics3D[Cuboid[{-.5, -.5, -.5}, {1., 2., 4}], ViewProjection -> "Orthographic", ViewPoint -> #1, ViewVertical -> #2] & @@@ v
Risposta
[Avviso di modifica: aggiornato per consentire limpostazione della direzione verticale del grafico e per correggere un errore .]
Ecco una leggera generalizzazione della mia risposta a Isometric 3d Plot . Per ottenere una vista isometrica, dobbiamo costruire un ViewMatrix
che ruoterà un vettore della forma {±1, ±1, ±1}
a {0, 0, 1}
e proiettare ortogonalmente sulle prime due coordinate.
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}]
Tutte le combinazioni di punti di vista e assi verticali:
Note:
Ottenere un intervallo di grafici accurato che includa il riempimento è importante per il calcolo la matrice di visualizzazione corretta. Esistono alternative alla funzione interna non documentata Charting`get3DPlotRange
. Alexey Popkov ha un metodo qui: Come ottenere il reale PlotRange utilizzando AbsoluteOptions? Ho usato PlotRange /. AbsolutOptions[g, PlotRange]
e moltiplicato per 1.02
(non ricordo perché non qualcosa come 1.04
) per approssimare il riempimento nella mia risposta a Grafico 3d isometrico .
La mia risorsa di riferimento per comprendere ViewMatrix
è stata soprattutto la risposta di Heike a Estrai i valori per ViewMatrix da un Graphics3D .
Questo aggiornamento è in risposta a Yves “ commento Lavorare con gli assi mi ha fatto capire che il sistema di coordinate è capovolto (da “destrorso” a “mancino). Quindi ho cambiato la proiezione da IdentityMatrix[4]
a una che capovolge le coordinate x & y.
Potrebbe essere una buona idea Deploy
la grafica per impedire la rotazione del mouse. Quando la grafica viene ruotata, il front-end reimposta ViewMatrix
in un modo piuttosto brutto.
Commenti
- Molto carino: è possibile allineare lasse z verticalmente?
- @YvesKlett È stato un po più difficile di quanto pensassi, principalmente perché avevo frainteso qualcosa.
- Fantastico! Questo ti tornerà utile!
Risposta
Puoi usare il seguente post -funzione di processo per applicare una proiezione parallela generale:
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]}]];
Qui axes
definisce la proiezione di x, y, assi z al piano 2d e pad
crea uno spazio per visualizzare le etichette degli assi.
Proiezione isometrica:
g = Graphics3D[Cuboid[], Axes -> True, AxesLabel -> {X, Y, Z}]; parallelProjection[g, {{-Sqrt[3]/2, -1/2}, {Sqrt[3]/2, -1/2}, {0, 1}}]
Proiezione cabinet:
α = π/4; parallelProjection[g, {{1, 0}, {0, 1}, -{Cos[α]/2, Sin[α]/2}}]
Risposta
Solo nel caso in cui non stiate cercando una soluzione completamente corretta, ma solo una soluzione economica.
Stavo cercando un tipo di soluzione ViewPoint->{Infinity,Infinity, Infinity}
. Sostituendo Infinity con un numero abbastanza grande (nel mio caso 500) ho potuto ottenere i risultati che stavo cercando.