Toutes les versions de cet article : [English] [français]
Depuis la version 7.9.1, MathGraph32 permet de créer des objets dans une figure en langage Python.
La figure ci-dessous crée cinq points libres A, B, C , D et E fournissant un polygone à 5 côtés puis appelle de façon itérative une fonction intSeg.
Si vous changez le code Python ci-dessous, cliquez sur le bouton Exécuter en dessous de ce cadre d’édition.
Vous trouverez en bas de cette page le code HTML ayant permis de la mettre en ligne.
Pour fonctionner correctement, cette figure a besoin d’un repère qui est fourni par le paramètre fig de la balise
Pour obtenir la suite du trajet des rebonds, cliquez sur les boutons + et - en bas et à droite qui font incrémenter ou décrémenter la variable p (valeur maxi de p : 50).
A noter que la figure obtenue est dynamique : vous pouvez capturer les points A, B, C, D, E M et N.
Les points A, B, C, D et E sont des points libres dont les coordonnées initiales dans le repère sont données lignes 83 à 87.
Si vous voulez que ces points soient fixes, remplacez ces cing lignes par les lignes suivantes (en modifiant les coordonnées à votre guise) :
A = addPointXY(-10, 8, 'A')
B = addPointXY(10, 8, 'B')
C = addPointXY(10, -8, 'C')
D = addPointXY(0, -2, 'D')
E = addPointXY(-10, -8, 'E')
Notez que, une fois le code Python exécuté, cliquer sur le bouton Télécharger la figure vous permet d’enregistrer la figure MathGraph32 que vous pourrez ensuite ouvrir avec le logiciel.
En utilisant l’outil Protocole vous verrez que cette figure est formée de plus de 3000 objets dont certains sont des matrices. Pourtant cette figure reste fluide !
Voici le code html qui a permis de mettre cette figure en ligne :
<script type = "text/mtgPython" id = "PythonCodeId">
# Fonction recherchant l'intersection de la demi-droite passant par pt et ayant un vecteur directeur de coordonnées (a, b) avec les côtés du polygone
# où a et b sont deux calculs réels de la figure
# Renvoie un tableau de la forme [ptret, u, v] où ptret est le point de rencontre et u et v deux calculs
# contenant les coordonnées d'un vecteur correspondant au "rebond"
def intSeg(pt, a, b, ind):
# On calcule les coordonnées de pt
addXMeasure(pt, f'xpt{ind}')
addYMeasure(pt, f'ypt{ind}')
trans = addTranslationxy(a, b)
ptim = addPointIm(pt, trans)
setHidden(ptim)
ray = addRay(pt, ptim)
setHidden(ray)
size = len(tabPt) - 1 # -1 car in a bouclé le tabelau en rajoutant le point de départ
# Pour savoir si pt est sur un des segments bords du polygone on crée des mesures d'abscisses de pt par rapport aux extrémités des segments
# et des tests d'existence de ces mesures
tabMesAbs = []
tabTestMesAbs = []
tabTestAbs = []
for i in range(size):
absMes = addAbsMeasure(pt, tabPt[i], tabPt[i + 1], f'mesAbs{ind}{i}')
tabMesAbs.append(absMes)
tabTestMesAbs.append(addTest(absMes, f'testMesAbs{ind}{i}'))
# Les test ci-dessous vaudront 1 si l'abscisse existe et est entre 0 et 1 et 0 sinon
tabTestAbs.append(addCalc(f'testAbs{ind}{i}', f'si(testMesAbs{ind}{i},mesAbs{ind}{i}>=0&mesAbs{ind}{i}<=1,0)'))
# On crée un tableau formé des points d'intersection de la demi-droite ray avec chacun des segments du polygone
tabInt = []
for i in range(size):
point = addIntLineLine(ray, tabSeg[i])
tabInt.append(point)
setHidden(point)
# On crée un tableau formé des abscisses des points d'intersections
tabAbs = []
for i in range(size):
tabAbs.append(addXMeasure(tabInt[i],f'xint{ind}{i}'))
# On crée un tableau formé des ordonnées des points d'intersections
tabOrd = []
for i in range(size):
tabOrd.append(addYMeasure(tabInt[i],f'yint{ind}{i}'))
# On crée un tableau formé des tests d'existence des abscisses pour savoir si les points existent
tabTest = []
for i in range(size):
tabTest.append(addTest(tabAbs[i], f'test{ind}{i}'))
# On va créer une matrice à cinq colonnes dont la première colonne contiendra le carré des distances entre pt
# et les points d'intersection de la demi-droite ray avec les côtés du polygone que ray rencontre à condition que pt ne soit pas sur ces segments
# les deuxième et troisième colonnes contenant l'abscisse et l'ordonnée de premier point du côté du polygone
# les quatrième et cinquième colonnes contenant les coordonnées de la première extrémité du segment correspondant
mat = []
matvalid = []
for i in range(size):
matvalid.append(f'test{ind}{i}&(1-testAbs{ind}{i})')
lig = [f'si(matvalid{ind}(1,{i}+1),(xint{ind}{i}-xpt{ind})^2+(yint{ind}{i}-ypt{ind})^2,10^99)', f'si(matvalid{ind}(1,{i}+1),xint{ind}{i},0)', f'si(matvalid{ind}(1,{i}+1),yint{ind}{i},0)', f'matAbs(1,{i} + 1)', f'matOrd(1,{i} + 1)']
mat.append(lig)
# La matrice V est une matrice ligne de par exemple 5 éléments si le polygone a 5 côtés
# Chacune de ses cellules conteint 1 si la demidroite rencontre le segment si si le point pt n'est pas sur ce segment
V = addMatrix(f'matvalid{ind}', [matvalid])
# Le calcul suivant contiendra la formule 1/0 si aucun point de rencontre entre la demi-droite et les segments n'est valide et 1 sinon
addCalc(f'valid{ind}', f'si(somme(matvalid{ind}(1,k), k, 1, {size}, 1)>0,1, 1/0)')
A = addMatrix(f'A{ind}',mat)
# La matrice B va contenir les lignes de la matrice A triés par sa première colonne en ordre croissant
B = addCalcMat(f'B{ind}', f'sortbycol(A{ind}, 1)')
xptret = addCalc(f'xptret{ind}', f'B{ind}(1,2)*valid{ind}') # Ce calcul n'existera pas si aucun point de rencontre entre la demi-droite et les segments n'est valide
yptret = addCalc(f'yptret{ind}', f'B{ind}(1,3)')
ptret = addPointXY(xptret, yptret) # Le point de rencontre entre la demi-droite et le segment le plus proche
addVector(pt,ptret, 'red')
extrem = addPointXY(f'B{ind}(1,4)', f'B{ind}(1,5)') #extrem est un point confondu avec une des extrémités du segment que la demi droite [pt, N) rencontre]
setHidden(extrem)
seg = addSegment(extrem, ptret) # segment partant du point d'intersection et le joignant à une des extémités du segment que la demi-droite rencontre
setHidden(seg)
perp = addLinePerp(ptret, seg) #perepndiculaire au segment rencontré au point de rencontre
setHidden(perp)
ptsym = addImPointSymAx(pt, perp) #Symétrique du point pt par rapport à la perpendiculaire
setHidden(ptsym)
xptsym = addXMeasure(ptsym, f'xptsym{ind}')
yptsym = addYMeasure(ptsym, f'yptsym{ind}')
xret = addCalc(f'xret{ind}', f'xptsym{ind}-xptret{ind}')
yret = addCalc(f'yret{ind}', f'yptsym{ind}-yptret{ind}')
# On renvoie le point de rencontre avec un des cinq segments et les coordonnés d'un vecteur joignant le point de rencontre au symétrique du point initial par rapport à la perpendiculaire au segment rencontré
return [ptret, xret, yret]
p = addVariable('p', 12, 0, 50, 1, True)
O = getPointByName('O') # L'origine du repère
A = addFreePoint(-10, 8, 'A')
B = addFreePoint(10, 8, 'B')
C = addFreePoint(10, -8, 'C')
D = addFreePoint(0, -2, 'D')
E = addFreePoint(-10, -8, 'E')
setPointNameOffset(A, -15, - 20)
setPointNameOffset(B, 5, - 20)
tabPt = [A, B, C, D, E]
# On referme le tableau de points
tabPt += [A]
tabSeg = []
tabAbs = []
tabOrd = []
for i in range(len(tabPt) - 1):
pt1 = tabPt[i]
pt2 = tabPt[i + 1]
tabAbs.append(addXMeasure(pt1, f'x{i}'))
tabOrd.append(addYMeasure(pt1, f'y{i}'))
tabSeg.append(addSegment(pt1, pt2))
# On crée deux matrices contenant les abscisses pour l'une et les ordonnées pour l'autre
addMatrix('matAbs', [tabAbs])
addMatrix('matOrd', [tabOrd])
pol = addPolygon(tabPt)
surf = addSurface(pol, 'green')
setHidden(pol)
M = addFreePoint(-7, -2, 'M', 'blue', 'X')
N = addFreePoint(-5, 4, 'N')
xM = addXMeasure(M, 'xM')
yM = addYMeasure(M, 'yM')
xN = addXMeasure(N, 'xN')
yN = addYMeasure(N, 'yN')
a = addCalc('a', 'xN-xM')
b = addCalc('b', 'yN-yM') # Le vecteur de coordonnées (a; b) donne la direction de la demi-droite [M,N)
point = M
x = a
y = b
for i in range(50):
# On crée un point image par l'homothétie de centre O et rapport 1/(i<=p). Quand i > p , le test (i<=p) renvoie comme valeur 0
# et le quotient 1/'i<=p) n'existe pas. Ainsi le point et les suivants n'existeront pas pour i > p
# On peut changer la valeur de p en cliquant sur les boutons + et - associés à la variable p en bas et à droite.
pointIm = addImPointDilation(point, O, f'1/({i}<=p)', f'N{i}')
setHidden(pointIm)
[point, x, y] = intSeg(pointIm, x, y, i)
</script>
<script async src="https://www.mathgraph32.org/js/mtgLoad/mathgraphElements.js"></script>
<mathgraph-player width="800" height="600" python-code-id="PythonCodeId" fig = "TWF0aEdyYXBoSmF2YTEuMAAAABUAAmZy####AQD#AQAAAAAAAAAABQUAAALHAAABAQAAAAAAAAABAAAANf####8AAAABAApDQ2FsY0NvbnN0AP####8AAnBpABYzLjE0MTU5MjY1MzU4OTc5MzIzODQ2#####wAAAAEACkNDb25zdGFudGVACSH7VEQtGP####8AAAABAApDUG9pbnRCYXNlAP####8AAAAAP4AAAAAOAAFPAMAoAAAAAAAAAAAAAAAAAAAAAAUAAUB5AAAAAAAAQHLKPXCj1wr#####AAAAAQAUQ0Ryb2l0ZURpcmVjdGlvbkZpeGUA#####wEAAAA#gAAAAA4AAAEAAAABAAAAAQE#8AAAAAAAAP####8AAAABAA9DUG9pbnRMaWVEcm9pdGUA#####wAAAAA#gAAAAQ4AAUkAwBgAAAAAAAAAAAAAAAAAAAAABQABQD0AAAAAAAAAAAAC#####wAAAAEACUNEcm9pdGVBQgD#####AAAAAD+AAAAAEAAAAQAAAAEAAAABAAAAA#####8AAAABABZDRHJvaXRlUGVycGVuZGljdWxhaXJlAP####8AAAAAP4AAAAAOAAABAAAAAQAAAAEAAAAE#####wAAAAEACUNDZXJjbGVPQQD#####AQAAAD+AAAAAAAABAAAAAQAAAAP#####AAAAAQAQQ0ludERyb2l0ZUNlcmNsZQD#####AAAABQAAAAb#####AAAAAQAQQ1BvaW50TGllQmlwb2ludAD#####AQAAAD+AAAAADgAAAQAABQABAAAABwAAAAkA#####wAAAAA#gAAAAQ4AAUoAwCgAAAAAAADAEAAAAAAAAAAABQACAAAAB#####8AAAACAAdDUmVwZXJlAP####8A5ubmP4AAAAADcmVwAAEAAAABAAAAAwAAAAkBAQAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABP#AAAAAAAAAAAAABP#AAAAAAAAD#####AAAAAQAKQ1VuaXRleFJlcAD#####AAR1bml0AAAACv####8AAAABAAtDSG9tb3RoZXRpZQD#####AAAAAf####8AAAABAApDT3BlcmF0aW9uAwAAAAE#8AAAAAAAAP####8AAAABAA9DUmVzdWx0YXRWYWxldXIAAAAL#####wAAAAEAC0NQb2ludEltYWdlAP####8BAAAAP4AAAAAQAAJXIgEAAAEAAAAAAwAAAAz#####AAAAAQAJQ0xvbmd1ZXVyAP####8AAAABAAAADf####8AAAABAAdDQ2FsY3VsAP####8AB25iZ3JhZHgAAjIwAAAAAUA0AAAAAAAAAAAAEQD#####AAduYmdyYWR5AAIyMAAAAAFANAAAAAAAAP####8AAAABABRDSW1wbGVtZW50YXRpb25Qcm90bwD#####ABRHcmFkdWF0aW9uQXhlc1JlcGVyZQAAABsAAAAIAAAAAwAAAAoAAAAPAAAAEP####8AAAABABNDQWJzY2lzc2VPcmlnaW5lUmVwAAAAABEABWFic29yAAAACv####8AAAABABNDT3Jkb25uZWVPcmlnaW5lUmVwAAAAABEABW9yZG9yAAAACgAAAAsAAAAAEQAGdW5pdGV4AAAACv####8AAAABAApDVW5pdGV5UmVwAAAAABEABnVuaXRleQAAAAr#####AAAAAQAQQ1BvaW50RGFuc1JlcGVyZQAAAAARAAAAAD+AAAAADgAAAQAABQAAAAAKAAAADgAAABIAAAAOAAAAEwAAABYAAAAAEQAAAAA#gAAAAA4AAAEAAAUAAAAACgAAAA0AAAAADgAAABIAAAAOAAAAFAAAAA4AAAATAAAAFgAAAAARAAAAAD+AAAAADgAAAQAABQAAAAAKAAAADgAAABIAAAANAAAAAA4AAAATAAAADgAAABUAAAAMAAAAABEAAAAWAAAADgAAAA8AAAAPAAAAABEAAAAAP4AAAAAOAAABAAAFAAAAABcAAAAZAAAADAAAAAARAAAAFgAAAA4AAAAQAAAADwAAAAARAAAAAD+AAAAADgAAAQAABQAAAAAYAAAAG#####8AAAABAAhDU2VnbWVudAAAAAARAQAAAD+AAAAAEAAAAQAAAAEAAAAXAAAAGgAAABcAAAAAEQEAAAA#gAAAABAAAAEAAAABAAAAGAAAABwAAAAEAAAAABEBAAAAP4AAAAALAAFXAMAUAAAAAAAAwDQAAAAAAAAAAAUAAT#cVniavN8OAAAAHf####8AAAACAAhDTWVzdXJlWAAAAAARAAZ4Q29vcmQAAAAKAAAAHwAAABEAAAAAEQAFYWJzdzEABnhDb29yZAAAAA4AAAAg#####wAAAAIAEkNMaWV1T2JqZXRQYXJQdExpZQEAAAARAGZmZj+AAAAAAAAAAB8AAAAOAAAADwAAAB8AAAACAAAAHwAAAB8AAAARAAAAABEABWFic3cyAA0yKmFic29yLWFic3cxAAAADQEAAAANAgAAAAFAAAAAAAAAAAAAAA4AAAASAAAADgAAACEAAAAWAAAAABEBAAAAP4AAAAALAAABAAAFAAAAAAoAAAAOAAAAIwAAAA4AAAATAAAAGQEAAAARAGZmZj+AAAAAAAAAACQAAAAOAAAADwAAAB8AAAAFAAAAHwAAACAAAAAhAAAAIwAAACQAAAAEAAAAABEBAAAAP4AAAAALAAFSAEAgAAAAAAAAwCAAAAAAAAAAAAUAAT#RG06BtOgfAAAAHv####8AAAACAAhDTWVzdXJlWQAAAAARAAZ5Q29vcmQAAAAKAAAAJgAAABEAAAAAEQAFb3JkcjEABnlDb29yZAAAAA4AAAAnAAAAGQEAAAARAGZmZj+AAAAAAAAAACYAAAAOAAAAEAAAACYAAAACAAAAJgAAACYAAAARAAAAABEABW9yZHIyAA0yKm9yZG9yLW9yZHIxAAAADQEAAAANAgAAAAFAAAAAAAAAAAAAAA4AAAATAAAADgAAACgAAAAWAAAAABEBAAAAP4AAAAALAAABAAAFAAAAAAoAAAAOAAAAEgAAAA4AAAAqAAAAGQEAAAARAGZmZj+AAAAAAAAAACsAAAAOAAAAEAAAACYAAAAFAAAAJgAAACcAAAAoAAAAKgAAACv#####AAAAAgAMQ0NvbW1lbnRhaXJlAAAAABEBZmZmP4AAAAAAAAAAAAAAAEAYAAAAAAAAAAAAAAAfCwAB####AAAAAQAAAAAAAAABAAAAAAAAAAAAAAsjVmFsKGFic3cxKQAAABkBAAAAEQBmZmY#gAAAAAAAAAAtAAAADgAAAA8AAAAfAAAABAAAAB8AAAAgAAAAIQAAAC0AAAAbAAAAABEBZmZmP4AAAAAAAAAAAAAAAEAYAAAAAAAAAAAAAAAkCwAB####AAAAAQAAAAAAAAABAAAAAAAAAAAAAAsjVmFsKGFic3cyKQAAABkBAAAAEQBmZmY#gAAAAAAAAAAvAAAADgAAAA8AAAAfAAAABgAAAB8AAAAgAAAAIQAAACMAAAAkAAAALwAAABsAAAAAEQFmZmY#gAAAAMAgAAAAAAAAP#AAAAAAAAAAAAAAACYLAAH###8AAAACAAAAAQAAAAEAAAAAAAAAAAAACyNWYWwob3JkcjEpAAAAGQEAAAARAGZmZj+AAAAAAAAAADEAAAAOAAAAEAAAACYAAAAEAAAAJgAAACcAAAAoAAAAMQAAABsAAAAAEQFmZmY#gAAAAMAcAAAAAAAAAAAAAAAAAAAAAAAAACsLAAH###8AAAACAAAAAQAAAAEAAAAAAAAAAAAACyNWYWwob3JkcjIpAAAAGQEAAAARAGZmZj+AAAAAAAAAADMAAAAOAAAAEAAAACYAAAAGAAAAJgAAACcAAAAoAAAAKgAAACsAAAAzAAAADv##########" >
</mathgraph-player>