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:
Lo cual está bien, pero tiene algunos problemas:
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.
¡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?
Sus requisitos:
Fácil de usar, obtuve la captura de pantalla anterior siguiendo estos pasos:
a = Vector((1, 2, 3))
, por ejemplo. 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 Text
comando: 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:
<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 .
Un par de ejemplos de MatPlotLib de la galería de gráficos 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()
'''
======================
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()
También recomendaría encarecidamente echar un vistazo a Jupyter + el núcleo VPython , ya que esto abre más posibilidades:
También sugeriría echar un vistazo al sitio de GlowScript que hace un uso extensivo de VPython:
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)