Graficar vectores simples, que van desde el origen del plano hasta un punto dado, en un espacio 3d

Quiero poder trazar vectores simples (no campos vectoriales ni nada más sofisticado) en un espacio 3D, como algunas líneas, cada una con una punta de flecha, que van desde el origen del plano hasta cualquier otro punto dado.

Cuanto más simple sea de usar (ingresar vectores, etiquetas, personalizar, etc.), mejor, ya que esta herramienta está pensada para ser utilizada en educación con una amplia gama de diferentes edades y niveles de experiencia.

Probé Matlab y Octave, y a través de quiver3 puedo hacer cosas como esta:

trazar vectores con ejemplo de octava

Lo cual está bien, pero tiene algunos problemas:

  1. Con la flexibilidad de esas herramientas también viene un costo de complejidad. En algunos rangos de edad y algunos niveles de experiencia perderé demasiado tiempo y atención usándolos.

  2. ¡En Octave, no puedo hacer que el eje pase por el origen! Se puede hacer en Matlab con una biblioteca de terceros, pero Matlab no es barato y, de todos modos, en esta tarea, los gráficos terminan pareciéndose a Octave.

Estoy buscando algo más simple para personalizar y trabajar, no necesito que sea flexible (busco personalizaciones muy simples, como posiciones de ejes, etiquetas, colores, etc.), no necesita realizar cálculos (solo se necesita la trama).

Como ejemplo, uso la calculadora gráfica Desmos para cosas en 2D todo el tiempo, aunque no es tan flexible y potente como los programas anteriores, es muy fácil hacer gráficos en 2D que se ven geniales con una personalización directa.

Entonces, ¿cuáles son las opciones/alternativas? ¿Qué usas para la escuela, el trabajo, el laboratorio?

Respuestas (2)

geogebra

Captura de pantalla de GeoGebra que muestra el panel Gráficos 3D y un vector ya ingresado a = (1, 2, 3)^T.  Además, la barra de entrada contiene "b = Vector((-3, 2, 1))", que el panel Gráficos 3D ya muestra en la vista previa.  El vector "a" también está pintado en verde y con un estilo de línea discontinua.

Sus requisitos:

  • Fácil de usar, obtuve la captura de pantalla anterior siguiendo estos pasos:

    • Iniciar GeoGebra
    • Seleccione en el menú Ver -> Gráficos 3D
    • En la barra de entrada, ingrese a = Vector((1, 2, 3)), por ejemplo.
      También puede ingresar un punto inicial y final para los vectores de dirección: Vector((1, 1, 1), (2, 2, 2)). Generalmente, ingresar cualquier comando ya muestra sus posibles parámetros y sobrecargas en forma de IntelliSense.
  • Las etiquetas se pueden crear usando el Textcomando: Text("hello", (1,1,1)).
    Asegúrese de hacer clic con el botón derecho en el objeto en el Panel de álgebra, seleccione Propiedades, Avanzado y active "Gráficos 3D" en Ubicación según esta respuesta .

  • Personalizable: al hacer clic con el botón derecho en cualquier objeto y seleccionar Propiedades, puede cambiar numerosas configuraciones, por ejemplo, el tamaño de fuente, el color y el estilo de línea.

Características generales:

  • Gratis y de código abierto
  • multiplataforma
  • Puede exportar imágenes a varios formatos (PNG, EPS y algunos códigos LaTeX)
  • Tiene soporte para secuencias de comandos JavaScript.
  • Admite "controles deslizantes variables" (piense <input type="range">si sabe HTML) y su modo de animación/aumento y disminución automáticos cada XX milisegundos.

Lo uso regularmente para dibujar cosas rápidamente o para obtener una comprensión intuitiva de algunas fórmulas. Sin embargo, una desventaja es que la barra de entrada/el sistema CAS a veces no puede comprender algunos comandos profundamente anidados que dependen de las variables del control deslizante.

Este tipo de cosas es ideal para hacer con python y una de las bibliotecas de trazado como MatPlotLib o Bokeh .

  • Gratis, gratis y de código abierto
  • Multiplataforma (se ejecutará en Windows, Mac o Linux y en una RaspberryPi hacia arriba)
  • Pequeña instalación
  • Flexible
  • Los gráficos se pueden guardar y exportar como archivos pdf o imágenes.

Un par de ejemplos de MatPlotLib de la galería de gráficos 3D :

Carcaj 3D:

==============
3D quiver plot
==============

Demonstrates plotting directional arrows at points on a 3d meshgrid.

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.gca(projection='3d')

# Make the grid
x, y, z = np.meshgrid(np.arange(-0.8, 1, 0.2),
                      np.arange(-0.8, 1, 0.2),
                      np.arange(-0.8, 1, 0.8))

# Make the direction data for the arrows
u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
     np.sin(np.pi * z))

ax.quiver(x, y, z, u, v, w, length=0.1, normalize=True)

plt.show()

Da:ingrese la descripción de la imagen aquí

Texto 3D

'''
======================
Text annotations in 3D
======================

Demonstrates the placement of text annotations on a 3D plot.

Functionality shown:
- Using the text function with three types of 'zdir' values: None,
  an axis name (ex. 'x'), or a direction tuple (ex. (1, 1, 0)).
- Using the text function with the color keyword.
- Using the text2D function to place text on a fixed position on the ax object.
'''

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt


fig = plt.figure()
ax = fig.gca(projection='3d')

# Demo 1: zdir
zdirs = (None, 'x', 'y', 'z', (1, 1, 0), (1, 1, 1))
xs = (1, 4, 4, 9, 4, 1)
ys = (2, 5, 8, 10, 1, 2)
zs = (10, 3, 8, 9, 1, 8)

for zdir, x, y, z in zip(zdirs, xs, ys, zs):
    label = '(%d, %d, %d), dir=%s' % (x, y, z, zdir)
    ax.text(x, y, z, label, zdir)

# Demo 2: color
ax.text(9, 0, 0, "red", color='red')

# Demo 3: text2D
# Placement 0, 0 would be the bottom left, 1, 1 would be the top right.
ax.text2D(0.05, 0.95, "2D Text", transform=ax.transAxes)

# Tweaking display region and labels
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
ax.set_zlim(0, 10)
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')

plt.show()

Da:ingrese la descripción de la imagen aquí

También recomendaría encarecidamente echar un vistazo a Jupyter + el núcleo VPython , ya que esto abre más posibilidades:

  • Gratis, gratis y de código abierto
  • Multiplataforma (se ejecuta en Windows, OS-X y Linux)
  • Interfaz a través del navegador web
  • Mucho más interactivo
  • Animación
  • Más agarre visual

También sugeriría echar un vistazo al sitio de GlowScript que hace un uso extensivo de VPython:ingrese la descripción de la imagen aquí

GlowScript 2.6 VPython

# Written by Bruce Sherwood, licensed under Creative Commons 4.0.
# All uses permitted, but you must not claim that you wrote it, and
# you must include this license information in any copies you make.
# For details see http://creativecommons.org/licenses/by/4.0

# Angular momentum of a binary star
scene.background = color.white
scene.y = 0
scene.width = 600
scene.height = 600
G = 6.7e-11
d = 1.5e11
star1 = sphere(pos=vector(d,0,0), radius=5e9, color=color.magenta, make_trail=True, retain=200, interval=10)
star1.mass = 1e30
star2 = sphere(pos=vector(0,0,0), radius=1e10, color=color.blue, make_trail=True, retain=200, interval=10)
star2.mass = 2*star1.mass

# make elliptical orbit in xz plane
ev = (2*pi*d/(365*24*60*60)) 
star1.p = vector(0, star1.mass*ev, 0)
star2.p = -star1.p
dt = 12*60*60

scene.center = vector(-0.2*d,0.3*d,0)
scene.range = 1.8*d # set size of window in meters
scene.forward = vector(0,1,-1) # tip camera angle
scene.lights = []
distant_light(direction=vector(0,-1,0.2))

# A in the xz plane
locationA = vector(-0.4*d, 0, 0) 

Lscale = 3.7e-35
pscale = 4e-24
offset = 2*star1.radius
h = star1.radius
Larr1 = arrow(pos=locationA-vector(offset,0,0), shaftwidth=star1.radius, axis=vector(0,0,0), color=star1.color)
rarr1 = arrow(pos=locationA, shaftwidth=star1.radius, axis=vector(0,0,0), color=color.cyan)
parr1 = arrow(pos=star1.pos, shaftwidth=star1.radius, axis=vector(0,0,0), color=color.red)
Larr2 = arrow(pos=locationA+vector(offset,0,0), shaftwidth=star1.radius, axis=vector(0,0,0), color=star2.color)
rarr2 = arrow(pos=locationA, shaftwidth=star1.radius, axis=vector(0,0,0), color=color.cyan)
parr2 = arrow(pos=star2.pos, shaftwidth=star1.radius, axis=vector(0,0,0), color=color.red)
Larr = arrow(pos=locationA, shaftwidth=star1.radius, axis=vector(0,0,0), color=vector(.7,.5,0))
Llabel1 = label(pos=locationA, text='L1', box=0, opacity=0, color=color.black)
Llabel2 = label(pos=locationA, text='L2', box=0, opacity=0, color=color.black)
Llabel = label(pos=locationA, text='L1+L2', box=0, opacity=0, color=color.black)

while True:
    rate(200)
    r = star2.pos-star1.pos
    F = -(G*star2.mass*star1.mass/mag(r)**2)*norm(r)
    star2.p = star2.p + F*dt
    star2.pos = star2.pos + (star2.p/star2.mass)*dt
    star1.p = star1.p - F*dt
    star1.pos = star1.pos + (star1.p/star1.mass)*dt
    parr2.pos = star2.pos
    parr2.axis = star2.p*pscale
    parr1.pos = star1.pos
    parr1.axis = star1.p*pscale
    rA1 = star1.pos-locationA
    rarr1.axis = rA1
    L1 = cross(rA1,star1.p)
    Larr1.axis = L1*Lscale
    rA2 = star2.pos-locationA
    rarr2.axis = rA2
    L2 = cross(rA2,star2.p)
    Larr2.axis = L2*Lscale
    Larr.axis = (L1+L2)*Lscale
    Llabel1.pos = Larr1.pos+Larr1.axis+vector(0,h,0)
    Llabel2.pos = Larr2.pos+Larr2.axis+vector(0,h,0)
    Llabel.pos = Larr.pos+Larr.axis+vector(0,h,0)