Er det mulig å gjengi Graphics3D
i en isometrisk projeksjon ? Jeg vet at alternativet ViewPoint
kan brukes til ortogonal projeksjon ved å spesifisere, f.eks. ViewPoint -> {0, Infinity, 0}
. Dette tar imidlertid ikke flere uendeligheter, så jeg kan ikke gjøre ViewPoint -> {Infinity, -Infinity, Infinity}
, for eksempel.
Jeg innser at jeg kunne oppnå dette ved å rotere hele scenen omtrent to akser og bruker en ortogonal projeksjon:
Graphics3D[ Rotate[ Rotate[ Cuboid[{-.5, -.5, -.5}], Pi/4, {0, 0, 1} ], ArcTan[1/Sqrt[2]], {0, 1, 0} ], ViewPoint -> {-Infinity, 0, 0} ]
Dette er imidlertid ganske tungvint, og det er vanskeligere å finne ut de riktige rotasjonene for synspunktet I » Jeg er interessert i. Jeg vil heller bare spesifisere oktanten man vil se scenen isometrisk fra. Er det faktisk en «riktig» måte å oppnå dette på?
Kommentarer
- Jeg gjorde en isometrisk projeksjon her: mathematica.stackexchange.com/questions/28000/isometric-3d-plot/… .
- @ MichaelE2 Å ok, jeg leste bare spørsmålet og så ikke ' hva det hadde med isometrisk tegning å gjøre (skulle har lest kommentarene også). Men jeg antar at tilnærmingen din ligner på min, bortsett fra at bruk av to vektorer for rotasjonen er obv veldig enklere enn å bruke to vinkler.
Svar
Fra og med V11.2 kan vi bruke en kombinasjon av ViewProjection
og ViewPoint
:
Graphics3D[Cuboid[], ViewProjection -> "Orthographic", ViewPoint -> {1, 1, 1}]
Ulike synspunkter:
v = Tuples[{Tuples[{-1, 1}, 3], IdentityMatrix[3]}]; Graphics3D[Cuboid[{-.5, -.5, -.5}, {1., 2., 4}], ViewProjection -> "Orthographic", ViewPoint -> #1, ViewVertical -> #2] & @@@ v
Svar
[Rediger varsel: Oppdatert for å tillate innstilling av loddrett retning for plottet og for å fikse en feil .]
Her er en liten generalisering av svaret mitt på Isometrisk 3d-plott . For å få en isometrisk visning må vi konstruere en ViewMatrix
som vil rotere en vektor med formen {±1, ±1, ±1}
til {0, 0, 1}
og projiser ortogonalt på de to første koordinatene.
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 kombinasjoner av synspunkter og vertikale akser:
Merknader :
Å få et nøyaktig plot-område som inkluderer polstring er viktig for databehandling riktig visningsmatrise. Det er alternativer til den udokumenterte interne funksjonen Charting`get3DPlotRange
. Alexey Popkov har en metode her: Hvordan få den virkelige PlotRange ved hjelp av AbsoluteOptions? Jeg brukte PlotRange /. AbsolutOptions[g, PlotRange]
og ganget med 1.02
(jeg husker ikke hvorfor ikke noe sånt som 1.04
) for å tilnærme polstringen i svaret mitt på Isometrisk 3d-plot .
Min ressurs for å forstå ViewMatrix
har vært spesielt Heikes svar på Pakk ut verdier for ViewMatrix fra en Graphics3D .
Denne oppdateringen svarer til Yves « Kommentar. Å jobbe med aksene fikk meg til å innse at koordinatsystemet er snudd (fra «høyrehendt» til «venstrehendt). Derfor endret jeg projeksjonen fra IdentityMatrix[4]
til en som vender x & y-koordinatene.
Det kan være en god idé å Deploy
grafikken for å hindre rotasjon av musen. Når grafikken roteres, tilbakestiller fronten ViewMatrix
på en ganske stygg måte.
Kommentarer
- Veldig fint – er det mulig å justere z-aksen vertikalt?
- @YvesKlett Det var litt vanskeligere enn jeg trodde det ville være, hovedsakelig fordi jeg hadde misforstått noe.
- Kjempebra! Denne vil komme godt med!
Svar
Du kan bruke følgende innlegg prosessfunksjon for å bruke en generell parallell projeksjon:
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]}]];
Her definerer axes
projeksjonen av x, y, z akser til 2d plan og pad
gir rom for å vise akselapper.
Isometrisk projeksjon:
g = Graphics3D[Cuboid[], Axes -> True, AxesLabel -> {X, Y, Z}]; parallelProjection[g, {{-Sqrt[3]/2, -1/2}, {Sqrt[3]/2, -1/2}, {0, 1}}]
Skapprojeksjon:
α = π/4; parallelProjection[g, {{1, 0}, {0, 1}, -{Cos[α]/2, Sin[α]/2}}]
Svar
Bare i tilfelle du ikke leter etter en helt riktig løsning, men i stedet bare en billig løsning.
Jeg lette etter en ViewPoint->{Infinity,Infinity, Infinity}
løsning. Ved å erstatte Infinity med et stort tall (i mitt tilfelle 500) kunne jeg få resultatene jeg lette etter.