Logiciel libre de géométrie, d'analyse et de simulation multiplateforme par Yves Biton

Accueil Tutoriels API Javascript, Python

Programar una figura en Python, incluso sin conexión

modification vendredi 27 mars 2026.

Toutes les versions de cet article : [English] [Español] [français]



Voici une traduction en espagnol, fidèle, fluide et adaptée à un contexte pédagogique :
— -
La versión 9.5 de MathGraph32 le permite ahora programar una figura en Python (o en Javascript) incluso sin estar en línea.
(Aun así, es necesario estar conectado la primera vez).

Para ello, se utiliza la versión de aplicación web de MathGraph32.

Basta con introducir en la barra de direcciones de su navegador lo siguiente :
https://app.mathgraph32.org/?loadPython=true

Se recomienda guardar el contenido de la barra de direcciones como un favorito del navegador para volver más fácilmente.

A continuación, podrá escribir código Python para actuar sobre una figura de MathGraph32 (por defecto, un sistema de ejes ortonormado), como en el ejemplo siguiente.

Una vez introducido su código Python, haga clic en el botón Ejecutar para ejecutar el código sobre la figura.

Si ha cometido errores, deberá consultar el contenido del campo Salida de la ejecución (abajo a la izquierda).

Dos botones situados encima le permiten abrir un archivo de código Python o guardar el código actual en un archivo.

Cabe señalar que si abandona la página y vuelve más tarde (o si la actualiza), el contenido del editor Python se rellenará con la última versión de su código.
Puede borrar el contenido del código Python haciendo clic en el botón Borrar.

Debajo, abajo a la derecha, el botón Descargar la figura le permite guardar el contenido de la figura en un archivo MathGraph32 (extensión mgj).

El botón Reiniciar con el ejemplo 1 sustituye el contenido del editor Python por un ejemplo muy sencillo de código Python.

El botón Importar le permite elegir como figura inicial la de su elección, en forma de código Base 64.

El botón Copiar el código de la figura copia el código Base 64 de la figura en el portapapeles.

El botón Mostrar el código de la figura abre un cuadro de diálogo que contiene el código Base 64 de la figura.

Cabe destacar que puede forzar el uso de un idioma distinto del francés.
Por ejemplo, para utilizar el inglés, introduzca en la barra de direcciones del navegador :

https://app.mathgraph32.org/?loadPython=true&language=eng
Para español será :

https://app.mathgraph32.org/?loadPython=true&language=esp
Para alemán :

https://app.mathgraph32.org/?loadPython=true&language=deu
Para árabe :

https://app.mathgraph32.org/?loadPython=true&language=ara

Para probar, introduzca en el editor Python el código del malabarista que encontrará al final de esta página (después de haber usado el botón Borrar).

Luego haga clic en el botón Ejecutar y después en el botón Start‑Stop de la figura.

Los artículos relacionados con Python en el sitio de MathGraph32 están aquí :
https://www.mathgraph32.org/spip.php?page=recherche&recherche=pythonfr

Para los aficionados a Javascript, también es posible programar una figura de MathGraph32 en Javascript de la misma manera : basta con introducir en la barra de direcciones :
https://app.mathgraph32.org/?loadJavascript=true

A continuación, el código Python del malabarista :

"""
Animación inspirada en el artículo de Vincent Pantaloni en este artículo de la APMEP: https://afdm.apmep.fr/rubriques/ouvertures/mathematiques-du-jonglage/
"""

ph = addCalc('ph', '0') # Añade a la figura MathGraph32 un cálculo cuyo valor será modificado en draw y permitirá la animación
n_balls = addCalc('nballs', '5') # Añade a la figura un cálculo llamado nballs. Modificable pero debe permanecer impar y >= 3
nballs = getValue(n_balls) # Devuelve el valor actual del cálculo MathGraph32 nballs
valph = 0
def draw(): # Función utilizada para la animación que cambia la fórmula del cálculo MathGraph32 ph y recalcula y redibuja los objetos que dependen de él
	global valph
	valph += 0.0075
	giveFormulaTo('ph', str(valph))
	updateDependantDisplay(ph) # Solo se calculan y redibujan los objetos que dependen del cálculo ph
	
dimf = getFigDim() # Devuelve una lista que contiene las dimensiones de la ventana de trabajo
width = dimf[0]
height = dimf[1]
zoomFig(width/2, height/2, 2) # Se hace un zoom de factor 2 sobre la figura
addTimerButton(draw, 1/60) # Añade un botón Start - Stop que llamará a la función draw sesenta veces por segundo
O = getPointByName('O') # Se memoriza el punto O, origen del sistema de referencia, como objeto punto (más rápido que referirse a su nombre más tarde)
setAngleUnity('radian') # Se impone el radian como unidad angular en la figura
# Inicio de la creación de los objetos gráficos fijos de la figura (que no dependen de ph)
head_0 = addPointXY(0, 2)
setHidden(head_0)
head_radius = 0.7
head = addCircleOr(head_0, head_radius, 'black', '-', 2)
head_0_position = getPointPosition(head_0)
head_base = addPointXY(head_0_position.x, head_0_position.y - head_radius)
setHidden(head_base)

spine_base = addPointXY(0, head_0_position.y - 4)
setHidden(spine_base)
torso = addSegment(head_base, spine_base, 'black', '-', 2)

shoulder_y = head_0_position.y - 1.5
l_shoulder = addPointXY(1.25, shoulder_y, '', 'black', 'O')
r_shoulder = addPointXY(-1.25, shoulder_y, '', "black", 'O')

shoulders = addSegment(l_shoulder, r_shoulder, 'black', '-', 2)
up_arm_0 = addPointXY(0.0, -1.0)
setHidden(up_arm_0)
    
l_arm_ph = addCalc('larmph', 'mod(nballs * ph,1)')
l_arm_th = addCalc('larmth', '2.0 * pi * larmph')

l_up_th = addCalc('lupth', '-0.25 * larmph * sin(larmth)')
v_l_up_arm = addImPointRotation(up_arm_0, O, l_up_th)
setHidden(v_l_up_arm)
l_elbow = addImPointTranslation(v_l_up_arm, O, l_shoulder)

l_forearm_x = addCalc('lforearmx', '-0.75 * cos(larmth)')
l_forearm_y = addCalc('lforearmy', '0.5 * (sin(larmth) - 0.8)')

v_l_forearm = addPointXY(l_forearm_x, l_forearm_y)
setHidden(v_l_forearm)
l_hand = addImPointTranslation(v_l_forearm, O, l_elbow)
mesabsleft = addXMeasure(l_hand, 'masabsleft')
mesordleft = addYMeasure(l_hand, 'masordleft')
l_hand_comp = addCalcComp('lhand', 'masabsleft + i*masordleft')

l_up_arm = addSegment(l_shoulder, l_elbow, 'green', '-', 2)
l_forearm = addSegment(l_elbow, l_hand, 'green', '-', 2)

r_arm_ph = addCalc('rarmph', 'mod(larmph + 0.5, 1)')
r_arm_th = addCalc('rarmth', '2.0 * pi * rarmph')

r_up_th = addCalc('rupth', '0.25 * rarmph * sin(rarmth)')

v_r_up_arm = addImPointRotation(up_arm_0, O, r_up_th)
setHidden(v_r_up_arm)
r_elbow = addImPointTranslation(v_r_up_arm, O, r_shoulder)

r_forearm_x = addCalc('rforearmx', '0.75 * cos(rarmth)')
r_forearm_y = addCalc('rforearmy', '0.5 * (sin(rarmth) - 0.8)')
v_r_forearm = addPointXY(r_forearm_x, r_forearm_y)
setHidden(v_r_forearm)
r_hand = addImPointTranslation(v_r_forearm, O, r_elbow)
mesabsright = addXMeasure(r_hand, 'mesabsright')
mesordright = addYMeasure(r_hand, 'mesordright')
r_hand_comp = addCalcComp('rhand', 'mesabsright+i*mesordright')
r_up_arm = addSegment(r_shoulder, r_elbow, 'red', '-', 2)
r_forearm = addSegment(r_elbow, r_hand, 'red', '-', 2)
# Fin de la creación de los objetos fijos de la figura (que no dependen de ph)

ball_colors = ["blue", "green", "red", "#ffbf00", "cyan"]

# En esta función, es necesario dar a los objetos de tipo cálculo MathGraph32 nombres que dependan de i, porque de lo contrario se producirán errores por cálculos creados con el mismo nombre
def make_ball(i):
	stri = str(i)
	j = 'j' + stri # Nombre del cálculo que representa el valor actual de i en los cálculos MathGraph32 siguientes
	addCalc(j, stri)
	ballph = 'ballph' + stri # Nombre del cálculo en mtg32
	ball_ph = addCalc(ballph, f"mod(2.0 * (ph * nballs + {j}),nballs * 2)") 
	airph = 'airph' + stri # Nombre del cálculo en mtg32
	# f seguido de " sirve para insertar en la cadena el contenido de variables de tipo cadena, rodeando su nombre con llaves. Así, {j} inserta el contenido de la variable j definida más arriba
	air_ph = addCalc(airph, f"mod({ballph}, nballs) / (nballs - 1)")
	airltorx = 'airltorx' + stri  # Nombre del cálculo en mtg32
	air_l_to_r_x = addCalc(airltorx, f"0.5 - {airph} * 2.5")
	airrtolx = 'airrtolx' + stri # Nombre del cálculo en mtg32
	air_r_to_l_x = addCalc(airrtolx, f"-0.5 + {airph} * 2.5")
	airy = 'airy' + stri # Nombre del cálculo en mtg32
	air_y = addCalc(airy, f"2 + 1.0 - 15.0 * ({airph} - 0.5)^2")
	airltor = 'airltor' + stri # Nombre del cálculo complejo en mtg32
	air_l_to_r = addCalcComp(airltor, f"{airltorx}+i*{airy}")
	airrtol = 'airrtol' + stri # Nombre del cálculo complejo en mtg32
	air_r_to_l = addCalcComp(airrtol, f"{airrtolx}+i*{airy}")
	# A continuación se define una fórmula de cálculo complejo válida para MathGraph32 (si se quiere que la figura sea dinámica no se debe usar la condición Python if)
	forcalc = f"si({ballph} <= nballs - 1, {airltor}, si({ballph} <= nballs ,rhand, si({ballph} <= 2*nballs - 1,{airrtol}, lhand)))"

	color = ball_colors[i % 5]
	point = addPointZ(f"{forcalc}", '') # El punto se define por su afijo complejo dado por la fórmula forcalc
	setHidden(point)
	circle = addCircleOr(point, 0.15, 'black', '-', 2)
	return addSurface(circle, color, 'fill')

for i in range(nballs):
    make_ball(i)