Is het mogelijk om Graphics3D
weer te geven in een isometrische projectie ? Ik weet dat de optie ViewPoint
kan worden gebruikt voor orthogonale projectie door bijvoorbeeld ViewPoint -> {0, Infinity, 0}
. Dit vereist echter niet meerdere oneindigheden, dus ik kan bijvoorbeeld niet ViewPoint -> {Infinity, -Infinity, Infinity}
doen.
Ik realiseer me dat ik dit zou kunnen bereiken door de hele scène te draaien over twee assen en met een orthogonale projectie:
Graphics3D[ Rotate[ Rotate[ Cuboid[{-.5, -.5, -.5}], Pi/4, {0, 0, 1} ], ArcTan[1/Sqrt[2]], {0, 1, 0} ], ViewPoint -> {-Infinity, 0, 0} ]
Dit is echter nogal omslachtig en “is moeilijker om de juiste rotaties voor het gezichtspunt I te bepalen” ben geïnteresseerd in. Ik “geef liever gewoon de octant op van waaruit de scène isometrisch moet worden bekeken. Is er eigenlijk een” juiste “manier om dit te bereiken?
Opmerkingen
- Ik heb hier een isometrische projectie gemaakt: mathematica.stackexchange.com/questions/28000/isometric-3d-plot/… .
- @ MichaelE2 Oh oké, ik heb alleen de hoofdtekst van de vraag gelezen en ' niet gezien wat het te maken had met isometrische plotten (zou heb ook de opmerkingen gelezen). Maar ik denk dat uw benadering vergelijkbaar is met die van mij, behalve dat het gebruik van twee vectoren voor de rotatie is veel eenvoudiger dan het gebruik van twee hoeken.
Answer
Vanaf V11.2 kunnen we een combinatie van ViewProjection
en ViewPoint
:
Graphics3D[Cuboid[], ViewProjection -> "Orthographic", ViewPoint -> {1, 1, 1}]
Diverse voordelen:
v = Tuples[{Tuples[{-1, 1}, 3], IdentityMatrix[3]}]; Graphics3D[Cuboid[{-.5, -.5, -.5}, {1., 2., 4}], ViewProjection -> "Orthographic", ViewPoint -> #1, ViewVertical -> #2] & @@@ v
Answer
[Bewerk kennisgeving: bijgewerkt om de instelling van de verticale richting van de plot mogelijk te maken en om een fout te herstellen .]
Hier is een kleine generalisatie van mijn antwoord op Isometrische 3D-plot . Om een isometrische weergave te krijgen, moeten we een ViewMatrix
construeren die een vector in de vorm {±1, ±1, ±1}
naar {0, 0, 1}
en projecteer orthogonaal op de eerste twee coördinaten.
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 combinaties van gezichtspunten en verticale assen:
Opmerkingen:
Het verkrijgen van een nauwkeurig plotbereik met de opvulling is belangrijk voor de berekening de juiste weergavematrix. Er zijn alternatieven voor de niet-gedocumenteerde interne functie Charting`get3DPlotRange
. Alexey Popkov heeft hier een methode: Hoe krijg ik de echte PlotRange met AbsoluteOptions? Ik gebruikte PlotRange /. AbsolutOptions[g, PlotRange]
en vermenigvuldigd met 1.02
(ik kan me niet herinneren waarom niet zoiets als 1.04
) om de opvulling in mijn antwoord op Isometrische 3D-plot .
Mijn belangrijkste bron voor begrip van ViewMatrix
is vooral het antwoord van Heike op Haal waarden voor ViewMatrix uit een Graphics3D .
Deze update is een reactie op Yves “ opmerking Het werken met de assen deed me beseffen dat het coördinatensysteem is omgedraaid (van “rechtshandig” naar “linkshandig). Daarom veranderde ik de projectie van IdentityMatrix[4]
naar een die de x & y coördinaten omdraait.
Het kan een goed idee om de afbeeldingen Deploy
te gebruiken om rotatie door de muis te voorkomen. Wanneer de afbeeldingen worden geroteerd, reset de voorkant de ViewMatrix
op een nogal lelijke manier.
Reacties
- Heel mooi – is het mogelijk om de z-as verticaal uit te lijnen?
- @YvesKlett Dat was een beetje moeilijker dan ik dacht dat het zou zijn, vooral omdat ik iets verkeerd had begrepen.
- Geweldig! Dit zal van pas komen!
Antwoord
Je kunt het volgende bericht gebruiken -procesfunctie om een algemene parallelle projectie toe te passen:
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 definieert axes
de projectie van x, y, z-as naar 2d-vlak en pad
maakt ruimte om aslabels weer te geven.
Isometrische projectie:
g = Graphics3D[Cuboid[], Axes -> True, AxesLabel -> {X, Y, Z}]; parallelProjection[g, {{-Sqrt[3]/2, -1/2}, {Sqrt[3]/2, -1/2}, {0, 1}}]
Kastprojectie:
α = π/4; parallelProjection[g, {{1, 0}, {0, 1}, -{Cos[α]/2, Sin[α]/2}}]
Antwoord
Voor het geval je niet op zoek bent naar een volledig correcte oplossing, maar in plaats daarvan naar een goedkope oplossing.
Ik was op zoek naar een ViewPoint->{Infinity,Infinity, Infinity}
soort oplossing. Door Infinity te vervangen door een getal dat groot genoeg is (in mijn geval 500), kon ik de resultaten krijgen waarnaar ik op zoek was.