¿Es posible renderizar Graphics3D
en un proyección isométrica ? Sé que la opción ViewPoint
se puede usar para la proyección ortogonal especificando, p. Ej. ViewPoint -> {0, Infinity, 0}
. Sin embargo, esto no toma múltiples infinitos, así que no puedo hacer ViewPoint -> {Infinity, -Infinity, Infinity}
, por ejemplo.
Me doy cuenta de que podría lograr esto rotando toda la escena sobre dos ejes y usando una proyección ortogonal:
Graphics3D[ Rotate[ Rotate[ Cuboid[{-.5, -.5, -.5}], Pi/4, {0, 0, 1} ], ArcTan[1/Sqrt[2]], {0, 1, 0} ], ViewPoint -> {-Infinity, 0, 0} ]
Sin embargo, esto es bastante engorroso y «es más difícil averiguar las rotaciones correctas para el punto de vista I» Estoy interesado. Preferiría especificar el octante desde el cual ver la escena isométricamente. ¿Existe realmente una forma «adecuada» de lograr esto?
Comentarios
- Hice una proyección isométrica aquí: mathica.stackexchange.com/questions/28000/isometric-3d-plot/… .
- @ MichaelE2 Oh, está bien, solo leí el cuerpo de la pregunta y no ' no vi lo que tenía que ver con el trazado isométrico (debería también he leído los comentarios). Pero supongo que su enfoque es similar al mío, excepto que el uso de dos vectores para la rotación es obvio Es mucho más simple que usar dos ángulos.
Respuesta
A partir de V11.2 podemos usar una combinación de ViewProjection
y ViewPoint
:
Graphics3D[Cuboid[], ViewProjection -> "Orthographic", ViewPoint -> {1, 1, 1}]
Varias ventajas:
v = Tuples[{Tuples[{-1, 1}, 3], IdentityMatrix[3]}]; Graphics3D[Cuboid[{-.5, -.5, -.5}, {1., 2., 4}], ViewProjection -> "Orthographic", ViewPoint -> #1, ViewVertical -> #2] & @@@ v
Respuesta
[Aviso de edición: actualizado para permitir la configuración de la dirección vertical del gráfico y corregir un error .]
Aquí hay una ligera generalización de mi respuesta a Gráfico 3D isométrico . Para obtener una vista isométrica, necesitamos construir un ViewMatrix
que rotará un vector de la forma {±1, ±1, ±1}
a {0, 0, 1}
y proyectarse ortogonalmente en las dos primeras coordenadas.
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}]
Todas las combinaciones de puntos de vista y ejes verticales:
Notas:
Obtener un rango de trazado preciso que incluya el relleno es importante para la computación la matriz de vista correcta. Hay alternativas a la función interna no documentada Charting`get3DPlotRange
. Alexey Popkov tiene un método aquí: ¿Cómo obtener el PlotRange real usando AbsoluteOptions? Usé PlotRange /. AbsolutOptions[g, PlotRange]
y lo multipliqué por 1.02
(no recuerdo por qué no algo como 1.04
) para aproximar el relleno en mi respuesta a Gráfica isométrica 3d .
Mi recurso de referencia para comprender ViewMatrix
ha sido especialmente la respuesta de Heike a Extrae valores para ViewMatrix de Graphics3D .
Esta actualización es en respuesta a Yves « comentario Trabajar con los ejes me hizo darme cuenta de que el sistema de coordenadas está invertido (de «diestro» a «zurdo). Por lo tanto, cambié la proyección de IdentityMatrix[4]
a una que invierte las coordenadas x & y.
Podría ser una buena idea Deploy
los gráficos para evitar la rotación del mouse. Cuando se rotan los gráficos, la interfaz reinicia ViewMatrix
de una manera bastante fea.
Comentarios
- Muy bien, ¿es posible alinear el eje z verticalmente?
- @YvesKlett Eso fue un poco más difícil de lo que pensé, principalmente porque había entendido mal algo.
- ¡Impresionante! ¡Esto será útil!
Respuesta
Puede usar la siguiente publicación -Función de proceso para aplicar una proyección paralela general:
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]}]];
Aquí axes
define la proyección de x, y, Z ejes al plano 2d y pad
crea un espacio para mostrar etiquetas de ejes.
Proyección isométrica:
g = Graphics3D[Cuboid[], Axes -> True, AxesLabel -> {X, Y, Z}]; parallelProjection[g, {{-Sqrt[3]/2, -1/2}, {Sqrt[3]/2, -1/2}, {0, 1}}]
Proyección del gabinete:
α = π/4; parallelProjection[g, {{1, 0}, {0, 1}, -{Cos[α]/2, Sin[α]/2}}]
Respuesta
En caso de que no esté buscando una solución completamente correcta, sino una solución alternativa barata.
Estaba buscando una ViewPoint->{Infinity,Infinity, Infinity}
tipo de solución. Reemplazando Infinity con un número lo suficientemente grande (en mi caso 500) podría obtener los resultados que estaba buscando.