Est-il possible de rendre Graphics3D
dans un projection isométrique ? Je sais que loption ViewPoint
peut être utilisée pour une projection orthogonale en spécifiant, par ex. ViewPoint -> {0, Infinity, 0}
. Cependant, cela ne prend pas plusieurs infinis, donc je ne peux pas faire ViewPoint -> {Infinity, -Infinity, Infinity}
, par exemple.
Je me rends compte que je pourrais y parvenir en faisant pivoter toute la scène sur deux axes et en utilisant une projection orthogonale:
Graphics3D[ Rotate[ Rotate[ Cuboid[{-.5, -.5, -.5}], Pi/4, {0, 0, 1} ], ArcTan[1/Sqrt[2]], {0, 1, 0} ], ViewPoint -> {-Infinity, 0, 0} ]
Cependant, cest plutôt encombrant et il « est plus difficile de déterminer les rotations correctes pour le point de vue I » Je suis intéressé. Je « préfère simplement spécifier loctant à partir duquel visualiser la scène de manière isométrique. Existe-t-il réellement un moyen » approprié « dy parvenir?
Commentaires
- Jai fait une projection isométrique ici: mathématique.stackexchange.com/questions/28000/isometric-3d-plot/… .
- @ MichaelE2 Oh daccord, je nai lu que le corps de la question et nai pas ' voir ce que cela avait à voir avec le traçage isométrique (devrait Jai lu les commentaires aussi). Mais je suppose que votre approche est similaire à la mienne, sauf que lutilisation de deux vecteurs pour la rotation est obv plus simple que d’utiliser deux angles.
Réponse
À partir de la version 11.2, nous pouvons utiliser une combinaison de ViewProjection
et ViewPoint
:
Graphics3D[Cuboid[], ViewProjection -> "Orthographic", ViewPoint -> {1, 1, 1}]
Divers avantages:
v = Tuples[{Tuples[{-1, 1}, 3], IdentityMatrix[3]}]; Graphics3D[Cuboid[{-.5, -.5, -.5}, {1., 2., 4}], ViewProjection -> "Orthographic", ViewPoint -> #1, ViewVertical -> #2] & @@@ v
Réponse
[Avis de modification: mis à jour pour permettre le réglage de la direction verticale du tracé et pour corriger une erreur .]
Voici une légère généralisation de ma réponse à Graphique 3D isométrique . Pour obtenir une vue isométrique, nous devons construire un ViewMatrix
qui fera pivoter un vecteur de la forme {±1, ±1, ±1}
à {0, 0, 1}
et projeter orthogonalement sur les deux premières coordonnées.
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}]
Toutes les combinaisons de points de vue et daxes verticaux:
Notes:
Obtenir une plage de tracé précise comprenant le remplissage est important pour le calcul la matrice de vue correcte. Il existe des alternatives à la fonction interne non documentée Charting`get3DPlotRange
. Alexey Popkov a une méthode ici: Comment obtenir le vrai PlotRange en utilisant AbsoluteOptions? Jai utilisé PlotRange /. AbsolutOptions[g, PlotRange]
et multiplié par 1.02
(je ne me souviens pas pourquoi quelque chose comme 1.04
) pour rapprocher le remplissage dans ma réponse à Graphique 3D isométrique .
Ma ressource incontournable pour comprendre ViewMatrix
a été en particulier la réponse de Heike à Extraire les valeurs pour ViewMatrix à partir dun Graphics3D .
Cette mise à jour est en réponse à Yves « commentaire Travailler avec les axes ma fait réaliser que le système de coordonnées est inversé (de « droitier » à « gauche »). Par conséquent, jai changé la projection de IdentityMatrix[4]
à une projection qui retourne les coordonnées x & y.
Cela pourrait être un bonne idée de Deploy
les graphiques pour empêcher la rotation par la souris. Lorsque les graphiques sont tournés, le frontal réinitialise le ViewMatrix
dune manière plutôt moche.
Commentaires
- Très bien – est-il possible daligner laxe z verticalement?
- @YvesKlett Cétait un peu plus difficile que je ne le pensais, principalement parce que javais mal compris quelque chose.
- Génial! Cette sera utile!
Réponse
Vous pouvez utiliser le message suivant -fonction de processus pour appliquer une projection parallèle générale:
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]}]];
Ici axes
définit la projection de x, y, les axes z vers le plan 2D et pad
crée une pièce pour afficher les étiquettes des axes.
Projection isométrique:
g = Graphics3D[Cuboid[], Axes -> True, AxesLabel -> {X, Y, Z}]; parallelProjection[g, {{-Sqrt[3]/2, -1/2}, {Sqrt[3]/2, -1/2}, {0, 1}}]
Projection du cabinet:
α = π/4; parallelProjection[g, {{1, 0}, {0, 1}, -{Cos[α]/2, Sin[α]/2}}]
Réponse
Juste au cas où vous ne chercheriez pas une solution complètement correcte, mais à la place, juste une solution de contournement bon marché.
Je cherchais une solution de type ViewPoint->{Infinity,Infinity, Infinity}
. En remplaçant Infinity par un nombre assez grand (dans mon cas 500), je pourrais obtenir les résultats que je recherchais.