Hypotrochoîdes amorties en python sous Gimp

Discutez d'informatique ici !
Machaon
Messages: 7
Enregistré le: 27 Fév 2013, 22:10

Hypotrochoîdes amorties en python sous Gimp

par Machaon » 28 Fév 2013, 23:58

Fou de photos, et à l'affût de nouveaux défis, j'ai photographié, depuis le sol, un pendule constitué d'une ampoule fixée sur une pile de 4,5v le tout suspendu par un fil au plafond.
Les figures obtenues n'ont de noms que ceux attribués aux recherches sur le web telles que hypotrochoîdes, ou plus proche, celles du pendule sphérique avec amortissement !

La partie mathématique sera transposée en language informatique à l'aide de python
(version parfaitement integrée à Gimp 2.8)

Comme me l'a suggéré LeJeu
Posté par LeJeu
Le forum 'informatique" me semble fait pour si tu veux causer de ton programme de dessin.

... causons donc du programme sans plus tardé.

Le but de ce WIP (Work In Progress) sera donc d'essayer de reproduire sous Gimp la jolie figure de ci-dessous.

Image

Et comme me l'a encore suggéré LeJeu
Posté par LeJeu
... tu as essayé ? tu en es où ?

... commençons ce premier post par le début en traçant une ellispe.

L'algorithme de tracé est conditionné par l'instruction suivante :
pdb.gimp_airbrush_default(drawable, num_strokes, strokes)
qui trace des segments entre les coordonnées de points (x,y) contenues dans un tableau.

Cette instruction utilise l'aérographe, pour un rendu plus réaliste. Il en existe 2 autres semblables :
pdb.gimp_paintbrush_default(drawable, num_strokes, strokes) pour le pinceau
pdb.gimp_pencil_default(drawable, num_strokes, strokes) pour le crayon

Le cercle sera donc décrit par des points (x,y) représentant des sommets reliés entre eux par des segments. Le tableau contenant ces points se nommera sommets et l'instruction de tracé aura la forme :
pdb.gimp_airbrush_default(calque, 2*nb_sommets, sommets)

Avec un calque de 1600 x 1200, nous prendrons 100 segments pour ressembler au mieux à la trace de l'ampoule sur la photo

Pour terminer cette introduction au tracé, il existe aussi l'instruction suivante qui ne "trace" que des points :
pdb.gimp_drawable_set_pixel(drawable, x_coord, y_coord, num_channels, pixel)

Voici le code commenté. (Je vous passe le bla-bla initial et le bla-bla final du script python)

Code: Tout sélectionner
# --- initialisations
   # --- premier calque
   premiercalque = img.layers[0]

   # --- dimensions image
   largeur = img.width
   hauteur = img.height

   # --- origines
   ox = largeur/2
   oy = hauteur/2

   # --- init rayons et segments
   initRayonA = 705
   initRayonB = 236
   nbSegments = 100

   # --- increment angulaire en radian des 100 sommets a tracer pour 2pi
   rdCote = 2 * pi/nbSegments
 
# --- remplissage tableau des 100 sommets de segments a tracer
   sommets = []
   for j in range(0,nbSegments):
         
      # --- coordonnees x et y du cercle
      x = sin(j * rdCote) * initRayonA + ox
      y = cos(j * rdCote) * initRayonB + oy

      # --- nombre entier pour pixel
      intx = int(x)
      inty = int(y)
      P = (intx ,inty)
      sommets.extend(P)

   # --- + le point du debut (soit pour sin 0 et cos 1) pour boucler
   # --- et ajouter +2 pour avoir un couple de plus
   x = ox
   y = initRayonB + oy
   intx =int(x)
   inty =int(y)
   P = (intx ,inty)
   sommets.extend(P)

# --- et trace avec Airbrush ...
   pdb.gimp_airbrush_default(premiercalque, 2*nbSegments+2, sommets)

# --- fastoche ...


Et l'image obtenue :

Image

Nous sommes encore loin de la figure de la photo ...

Cette étape de débrouissaillage python était, je pense, nécessaire pour passer tranquillement à la suite.

La suite au prochain post ... comme l'a deviné encore LeJeu
Posté par LeJeu
... Sinon, le point parcourant un ellipse, celle ci tournant sur elle même ( précession) ne te donne pas une bonne modélisation ?

... ben c'est là qu'il risque d'y avoir un problème (d'amortissement) ! :lol2:
on fera tourner 123 fois le repére de cette ellispe ... enfin j'espère.

Dans l'étape suivante le repère subira un amortissement dans sa rotation ... et à ce moment là j'aurais besoin d'un coup de main. :lol2:



LeJeu
Membre Irrationnel
Messages: 1141
Enregistré le: 24 Jan 2010, 22:52

par LeJeu » 01 Mar 2013, 09:34

Machaon a écrit:Nous sommes encore loin de la figure de la photo ...



Moi je trouve que c'est pas mal ....

pour la précession, je dirais que l'ellipse tourne sur elle même d'environ un douxième de quart de tour à chaque fois

en changeant dans ton code
x = ox + delta_x
y = Oy +delta_y

en x = ox + cos(phi)*delta_x -sin(phi)*delta_y
et y = oy + sin(phi)*delta_x + sin(phi)* delta_y

avec PHI = 2pi / 48 pour un tour d'ellipse
donc phi = 2pi /48 /nbsegments à chaque calcul ca devrait tourner !

il faut ensuite ajouter une boucle pour dessiner plusieurs ellipses de suite, douze tours pour voir notre ellipse faire un quart de tour

[edit] - je te lasse attaquer le POC ( Proof Of Concept) :-)

LeJeu
Membre Irrationnel
Messages: 1141
Enregistré le: 24 Jan 2010, 22:52

par LeJeu » 01 Mar 2013, 22:15

LeJeu a écrit:donc phi = 2pi /48 /nbsegments à chaque calcul ca devrait tourner !
il fallait bien sûr lire Phi augmente de 2PI/48/nbsegments à chaque calcul

Joker62
Membre Transcendant
Messages: 5028
Enregistré le: 24 Déc 2006, 20:29

par Joker62 » 02 Mar 2013, 14:04

Hello !

Si c'est comme le pendule sphérique, n'est-ce-pas plus simple d'approcher la solution
par un système numérique type Euler Implicite ou autre plus précis ?

Les logiciels de maintenant font ça très bien non ?

Joker62
Membre Transcendant
Messages: 5028
Enregistré le: 24 Déc 2006, 20:29

par Joker62 » 02 Mar 2013, 16:47

Re,

Avec Scilab et un Schéma d'Euler Explicite (Le plus simple possible donc) (et qui n'est pas très stable)
On obtient ceci :

http://mathmoica.free.fr/Pendule.m4v

Pendule Sphérique avec amortissement
Les données

Masse = 1 kg
Accélération de pesanteur = 9.81
Longueur = 1m

Amortissement = 0.1

Valeur Init

Angle Init = [;)/3,;)/4]
Vitesse Init = 1 (suivant la normale)
Vitesse Init = 5 (suivant le déplacement)

Machaon
Messages: 7
Enregistré le: 27 Fév 2013, 22:10

par Machaon » 02 Mar 2013, 17:16

Dans le précédent post, nous avons tracé une ellipse sous Gimp.
Cette ellipse est un classique cercle de coordonnées :
x = sin(a) * rayonA
y = cos(a) * rayonB
avec 2 rayons A et B différents

Pour rappel, l'instruction choisie sous Gimp pour tracer le cercle impose un tableau de sommets.
Le cercle sera décrit par des points (x,y) représentant ces sommets, reliés entre eux par des segments.

Le seul impératif est de formater les x et y en entiers pour correspondre à des pixels sous Gimp.
Le typage des données sous Python est automatique (malheureusement!) et il faut dans certains cas forcer le type.

L'image sous Gimp a ses coordonnées (0,0) en haut à gauche, et le sens de rotation positif est anti-horaire.

Attaquons la rotation des axes du repère du tracer de l'ellipse.

Un petit rappel sur les formules de changement d'axes de coordonnées.
Exprimons les coordonnées d'un point M dans l'un des repères en fonction des coordonnées dans l'autre repère.

Image

Dans un repère xOy les coordonnées (x,y) d'un point M s'expriment en fonction des coordonnées polaires (r,;)) par les formules suivantes :



Dans le nouveau repère x'Oy' déduit du précédent par une rotation d'angle ;) (voir la figure) les nouvelles coordonnées polaires sont r et (;) - ;)) et les coordonnées cartésiennes deviennent :



En développant les fonctions trigonométriques et en tenant compte des expressions de x et y, on arrive aux formules suivantes permettant de passer d'un repère à l'autre.



Ce changement de repère s'intercalera dans le programme sous la forme
Code: Tout sélectionner
# --- nouveau repere en fonction de sa rotation
   xx = x * cos(initRepAng) + y * sin(initRepAng) + ox
   yy = -x * sin(initRepAng) + y * cos(initRepAng) + oy

Le repère tournera ici de 38 tours (au lieu de 123 prévu), pour une rotation totale [rotTotRepAng] de 180° à partir d'une position angulaire initiale de + 5.05° mesurée sur le modèle par rapport à l'horizontale .
Cette rotation sera effectuée par une boucle externe à la première.
Code: Tout sélectionner
   for i in range(nbTours):

Calculons l'incrémentation moyenne de la rotation du repère par tour :
moyenIncRepAng = rotTotRepAng / (nbTours * nbSegments)

Et l'incrément à ajouter à [initRepAng] pour chaque segment :
initRepAng = initRepAng + moyenIncRepAng
et ... à chaque calcul, comme l'a suggéré LeJeu

Ne pas oublier d'adapter le code calculant le dernier segment pour boucler l'ellipse !
Code: Tout sélectionner
# --- + point du debut (soit sin 0 et cos 1) pour boucler
   x = 0
   y = initRayonB

   # --- nouveau repere avec x=0
   xx = y * sin(initRepAng) + ox
   yy = y * cos(initRepAng) + oy
   intx =int(xx)
   inty =int(yy)
   P = (intx ,inty)
   sommets.extend(P)

Un petit raffinement de couleur à mi-chemin pour terminer avec le code
Code: Tout sélectionner
# --- changement couleur pinceau
   if i > (nbTours -1)/2:
      pdb.gimp_context_set_foreground((255, 0, 0))   # --- rouge
   else:
      pdb.gimp_context_set_foreground((255, 255, 255))# --- blanc

Un mot encore sur les valeurs des rayons A et B :
- rayon A initial : 705
- rayon B initial : 236
- rayon A initial : 459
- rayon B initial : 140
Toutes ces valeurs ont été mesurées avec Gimp sur le modele
Les décrémentations des 2 rayons sont linéaires ... pour le moment !

Le code principal complet :
Code: Tout sélectionner
# --- initialisations principales

   # --- dimensions image
   largeur = img.width
   hauteur = img.height

   # --- origines
   ox = largeur/2
   oy = hauteur/2

   # --- init diverses
   initRayonA = 705
   initRayonB = 236
   finalRayonA = 459
   finalRayonB = 140

   initRepAng  = 5.05 * rad
   rotTotRepAng  = 176.87 * rad

   nbTours = 38
   nbSegments = 100

   # --- increment angulaire en radian des 100 sommets a tracer pour 2pi
   rdCote = 2 * pi/nbSegments

# --- calcul incrementations lineaires des cercles A et B
incRayonA = (initRayonA - finalRayonA) / (nbTours * nbSegments * 1.00)    # --- * 1.00 pour forcer en FLOAT
incRayonB = (initRayonB - finalRayonB) / (nbTours * nbSegments * 1.00)    # --- * 1.00 pour forcer en FLOAT

# --- calcul incrementation lineaire moyenne de la rotation du repere par tour
moyenIncRepAng = rotTotRepAng / (nbTours * nbSegments)
 

# --- boucle de trace
for i in range(nbTours):

      #  ---  tableau sommets des segments a tracer
      sommets = []
      for a in range(0,nbSegments):

         # --- incrementation petit cercle initRayonA avec incRayonA en PF      
         initRayonA = initRayonA - incRayonA
         initRayonB = initRayonB - incRayonB
         
         # --- coordonnees x et y du cercle
         x = (sin(a * rdCote) * initRayonA)
         y = (cos(a * rdCote) * initRayonB)

         # --- nouveau repere en fonction de sa rotation
         xx = x * cos(initRepAng) + y * sin(initRepAng) + ox
         yy = -x * sin(initRepAng) + y * cos(initRepAng) + oy

         # --- nombre entier pour pixel
         intx =int(xx)
         inty =int(yy)
         P = (intx ,inty)
         sommets.extend(P)

         # --- incrementation moyenne de la rotation du repere
         initRepAng = initRepAng + moyenIncRepAng

      # --- + point du debut (soit sin 0 et cos 1) pour boucler
      # --- et ajouter +2 pour avoir un couple de plus
      x = 0
      y = initRayonB
      xx = y * sin(initRepAng) + ox    # -- x=0 dans le nouveau repere
      yy = y * cos(initRepAng) + oy
      intx =int(xx)
      inty =int(yy)
      P = (intx ,inty)
      sommets.extend(P)

      # --- Trace avec Airbrush
      pdb.gimp_airbrush_default(premiercalque,2*nbSegments+2,sommets)

      # --- changement couleur pinceau
      if i > (nbTours -1)/2:
         pdb.gimp_context_set_foreground((255, 0, 0))        # --- rouge
      else:
         pdb.gimp_context_set_foreground((255, 255, 255)) # --- blanc

Pour finir l'image obtenue des 38 tours pour 180° à partir de la position initiale 5.05°.

Image

38 tours avec incrémentation linéaire, autrement dit sans amortissement ...

Joker62 a écrit:Hello !

Si c'est comme le pendule sphérique, n'est-ce-pas plus simple d'approcher la solution
par un système numérique type Euler Implicite ou autre plus précis ?

Les logiciels de maintenant font ça très bien non ?


Merci pour ta judicieuse proposition, si un logiciel peut aider à la solution, je suis preneur. :lol2:
Je termine la mise en place du "squelette de traçage de courbe" sous python que je découvre par la même occasion. La suite ... essayer de trouver l'amortissement, ou les amortissements, "un peu fous" de ce diable de pendule, avec votre aide.

Pour les photos, le pendule était "jeté" en le décalant du centre ! Suivant la force et la direction de ces "jetés" la photo était excellente ou très mauvaise !
Quant à l'étude menée ici du pendule sphérique, puisque la ressemblance est assez troublante, seuls les plans x et y sont intégrés. Si l'étude aboutit, au moins approximativement, j'envisage de poursuivre, cette fois avec z, dans mon logiciel préféré de 3D.

Au prochain post je vous livre les relevés des angles et de la longueur du grand rayon sur le modèle.

Merci à LeJeu de me suivre :++:

Edit : Merci Joker62 pour l'info qui est arrivée en même que la publication de mon post

Joker62
Membre Transcendant
Messages: 5028
Enregistré le: 24 Déc 2006, 20:29

par Joker62 » 02 Mar 2013, 17:45

Oui donc le graphique ne correspond pas à la modélisation d'un pendule sphérique amorti.

C'est juste une ellipse qui tourne et qui se réduit.

Machaon
Messages: 7
Enregistré le: 27 Fév 2013, 22:10

par Machaon » 02 Mar 2013, 20:29

Joker62 a écrit: ....C'est juste une ellipse qui tourne et qui se réduit.

Nous sommes d'accord, il s'agit, pour le moment d'une ellipse qui tourne et qui se réduit.

D'ailleurs en prenant les données du modèle :
- initRayonA = 705
- initRayonB = 236
- finalRayonA = 265
- finalRayonB = 30
- nbTours = 123
- rotTotRepAng = 320.76

la figure produite ressemble à ceci :
Image

Ce qui est très loin du but recherché dans le modèle en rappel ci-dessous, qui ressemble à un pendule sphérique amorti ...

Image

LeJeu
Membre Irrationnel
Messages: 1141
Enregistré le: 24 Jan 2010, 22:52

par LeJeu » 04 Mar 2013, 22:52

Machaon a écrit:Nous sommes d'accord, il s'agit, pour le moment d'une ellipse qui tourne et qui se réduit
.../...

Ce qui est très loin du but recherché dans le modèle en rappel ci-dessous, qui ressemble à un pendule sphérique amorti ...



Moi je dis que c'est exactement ce que l'on veut ? la trajectoire d'un pendule sphérique projeté sur le plan Oxy, est bien localement approximé par une ellipse ?

Par contre oui, il faut amortir, j'ai donc choisi de faire tourner une ellipse en amortissant son grand axe, de façon différente son petit axe( donc e non constant), et sa vitesse de précession

6 paramètres donc
3 valeurs initiales : petit axe / grand axe /vitesse de précession
et 3 amortis exponentiels indépendants

ce qui donne


Image

n'est ce pas joli :-)

J'ai fait rapidos pour choisir les constantes, on doit faire mieux en s'appliquant

MAIS peut être manque t'il encore le facteur 'surexposition' de la photo , quand le pendule ralenti ? peut être en augmentant l'épaisseut du trait en fct des tours

PS - zéro programmation pour le bidule ci-dessus ..

Machaon
Messages: 7
Enregistré le: 27 Fév 2013, 22:10

par Machaon » 05 Mar 2013, 00:15

Merci pour ta réponse LeJeu.
Waou super jolie ta photo :lol2:

LeJeu a écrit:Moi je dis que c'est exactement ce que l'on veut ? la trajectoire d'un pendule sphérique projeté sur le plan Oxy, est bien localement approximé par une ellipse ?..

D'accord ...

6 paramètres donc
3 valeurs initiales : petit axe / grand axe /vitesse de précession
et 3 amortis exponentiels indépendants


Ben voilà, tu as tout dit : "les 3 amortis" ... C'est exactement ce que j'essaie d'exprimer depuis le début.

Tu dis amortis "exponentiels".
Un truc amortissement exponentiel du genre :
100*(1 - Exp ( -c*t)) ou c correspond à la vitesse de l'amortissement.
J'attends avec impatience tes constantes !

Tu as (encore) raison avec l'épaisseur du trait, ou bien sa luminosité, ou les deux, qui devraient varier
vers une surexposition vers la fin des tours. Cet état était plus ou moins prévu par l'emploi à la base de l'aérographe, à condition de trouver le paramètre adéquate.

C'est quoi ce PS "zéro programmation pour le bidule ci-dessus" ? Magnifique ce dessin ! Mais comment as-tu réalisé cet exploit ? Avec un logiciel de dessin pas par pas ? :lol2:

Comme promis, en image ci-dessous les 79 premiers relevès (sur 123) en angle et en grande longueur de l'ellipse. (Avec des courbes de tendance pour gommer les imperfections de relevès)

Image

Curieux cette courbe d'amortissement. Le début correspondrait à un résidu de vitesse initiale lors du "jeté" de pendule ?

En bonus d'autres photos de mon montage.

Image

Merci sincèrement LeJeu de toute l'attention que tu portes à mes déboires grapho-pseudo-mathématico-pythonesque. :++:

LeJeu
Membre Irrationnel
Messages: 1141
Enregistré le: 24 Jan 2010, 22:52

par LeJeu » 05 Mar 2013, 02:26

Machaon a écrit:En bonus d'autres photos de mon montage.

Et celle-ci , tu as ?

Image

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 12 invités

cron

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite