¿Cómo dibujar planos que se cruzan?

Quiero usar matplotlib para dibujar más o menos la figura que adjunto a continuación, que incluye los dos planos de intersección con la cantidad correcta de transparencia que indica sus orientaciones relativas, y los círculos y vectores en los dos planos proyectados en 2D.

No estoy seguro de si hay un paquete existente para hacer esto, ¿alguna sugerencia? Crédito de la imagen: M Strassler

from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt import numpy as np fig = plt.figure() ax = fig.add_subplot(111, projection='3d') dim = 10 X, Y = np.meshgrid([-dim, dim], [-dim, dim]) Z = np.zeros((2, 2)) angle = .5 X2, Y2 = np.meshgrid([-dim, dim], [0, dim]) Z2 = Y2 * angle X3, Y3 = np.meshgrid([-dim, dim], [-dim, 0]) Z3 = Y3 * angle r = 7 M = 1000 th = np.linspace(0, 2 * np.pi, M) x, y, z = r * np.cos(th), r * np.sin(th), angle * r * np.sin(th) ax.plot_surface(X2, Y3, Z3, color='blue', alpha=.5, linewidth=0, zorder=-1) ax.plot(x[y < 0], y[y < 0], z[y < 0], lw=5, linestyle='--', color='green', zorder=0) ax.plot_surface(X, Y, Z, color='red', alpha=.5, linewidth=0, zorder=1) ax.plot(r * np.sin(th), r * np.cos(th), np.zeros(M), lw=5, linestyle='--', color='k', zorder=2) ax.plot_surface(X2, Y2, Z2, color='blue', alpha=.5, linewidth=0, zorder=3) ax.plot(x[y > 0], y[y > 0], z[y > 0], lw=5, linestyle='--', color='green', zorder=4) plt.axis('off') plt.show() 

resultado

advertencias

  • Estoy ejecutando una versión muy cercana al maestro actual, así que no estoy seguro de qué funcionará en versiones anteriores

  • La razón para dividir la ttwig es que ‘arriba’ y ‘abajo’ están determinados de alguna manera arcana (no estoy estrictamente seguro de que zorder realmente haga nada), y realmente depende del orden en que se dibujan los artistas. Por lo tanto, las superficies no pueden intersecarse (una estará por encima de la otra en todas partes), por lo que debe trazar las secciones a cada lado de la intersección por separado. (Puedes ver esto en la línea negra en la que no me separé, así se ve en ‘en la parte superior’ del plano azul superior).

  • El ordenamiento ‘correcto’ de las superficies también parece depender del ángulo de visión.

Matplotlib tiene capacidad de proyección en 3D, pero las líneas discontinuas se dibujan con un ancho constante en la vista de la imagen 2D final, sin verse como si estuvieran planas en los planos inclinados. Si la geometría es simple, y las “órbitas” son circulares, podría funcionar, pero si desea dibujar puntos suspensivos vistos en un ángulo, el espectador puede desear más pistas visuales sobre toda la disposición 3D.

Si tuviera que hacer una bonita ilustración elegante como esa, pero aún más bonita y elegante, y no tenía que ser automatizada, comenzaría por crear los gráficos, al menos los círculos de líneas discontinuas, para cada uno de los planos como una imagen plana simple en 2D que use lo que parezca útil en este momento: un progtwig de dibujo vectorial como Illustrator o Inkscape, o en matplotlib si hay datos a seguir.

Luego, usaría POV-Ray o Blender para modelar los planos en cualquier ángulo, esferas para las cosas redondas (¿planetas?). Los gráficos 2D ya generados se convertirían en texturas para ser asignados a los planos. POV-Ray utiliza un lenguaje de scripting que permite mantener, modificar y copiar un registro para futuros proyectos. Si realmente fue una sola vez y no me importó hacerlo todo a mano, Blender es bueno. Cualquiera que sea la herramienta que use, el resultado es una imagen que muestra la proyección deseada de los elementos geométricos 3D en 2D.

¿Se supone que las cosas redondas, lo que yo llamo “planetas” son círculos planos en el trabajo final, como en los ejemplos? Luego los dibujaría con una aplicación de dibujo vectorial sobre la imagen 3D renderizada. Pero sospecho que preferirías esferas en 3D.

Las muestras mostradas no tienen iluminación ni sombras. Las sombras ayudarían a aclarar la geometría en 3D, aunque la primera de esas dos ilustraciones no es tan mala. La línea verde corta que muestra el planeta del plano inclinado sobre la línea roja parece suficientemente clara, pero una sombra ayudaría. La segunda ilustración parece un poco más confusa en cuanto a la forma, la ubicación y las intersecciones de las diversas entidades. Aquí, las sombras ayudarían más. POV-Ray o Blender felizmente crearán estos con poco esfuerzo. Aún más, las interreflexiones, conocidas como radiosidad, ayudan a ver las relaciones 3D en imágenes 2D. Este efecto avanzado es fácil de hacer en estos días, ya que no necesita experiencia en óptica o gráficos, solo sabiendo que existe.

Por supuesto, este consejo no es bueno a menos que uno ya esté familiarizado con los gráficos en 3D y herramientas como POV-Ray.

Para una solución automatizada, usar OpenGL en algún progtwig rápido y sucio puede ser lo mejor. Sin embargo, las sombras pueden requerir algo de trabajo.