Points animés

Discutez d'informatique ici !
t.itou29
Membre Rationnel
Messages: 601
Enregistré le: 22 Jan 2013, 16:20

points animés

par t.itou29 » 15 Avr 2014, 20:40

Bonsoir,
Pour modéliser un problème de maths, j'essaie de faire un programme: j'ai n points qui tournent autour d'un cercle et je connais leur coordonnées à un instant t. J'ai réussi à faire un programme qui à chacun des points associe ses coordonnées au moment t (en fait des intervalles de 10^-5s) mais j'aimerais pouvoir afficher ces points sur le cercle et de manière dynamique. C'est à dire pouvoir visualiser les points se déplaçant sur le cercle. Je viens de commencer la programmation et j'ai cherche sur Google mais je n'ai rien trouvé que je comprenne très bien... Il n'y pas de commande simple qui affiche un point de coordonnées (x,y) dans un répère ? (Sur python) Pouvez me donner un exemple de code ?



Cliffe
Membre Rationnel
Messages: 967
Enregistré le: 12 Juin 2012, 13:25

par Cliffe » 16 Avr 2014, 13:31

Utilise Maple

t.itou29
Membre Rationnel
Messages: 601
Enregistré le: 22 Jan 2013, 16:20

par t.itou29 » 16 Avr 2014, 13:54

Cliffe a écrit:Utilise Maple

Je viens de regarder c'est assez cher (plus de 100 euros!), à mois qu'il y ait moyen de le télécharger plus ou moins légalement... ?
J'aimerais bien le faire avec python ça me permettrait de progresser, c'est vraiment compliqué ?

Cliffe
Membre Rationnel
Messages: 967
Enregistré le: 12 Juin 2012, 13:25

par Cliffe » 16 Avr 2014, 14:00

Y'a pas mieux que maple pour les animations, surtout pour les maths.
A toi de voir.

Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 16 Avr 2014, 14:41

Y'a pas mieux que maple pour les animations, surtout pour les maths.

complètement subjectif.

J'aimerais bien le faire avec python ça me permettrait de progresser, c'est vraiment compliqué ?

j'ai pas non plus bcp d'expérience avec python, mais je peux au moins affirmer que c'est facile.
Toute ce que t'as à faire c'est de chercher un canvas, probablement tkinter, qui te propose une api, style plotCircle (pour faire des points) ou plotArc(angle 2PI) pour faire un cercle.
Généralement ces méthodes prennent en arguments x et y...donc tu devrais pas trop suer.
la vie est une fête :)

t.itou29
Membre Rationnel
Messages: 601
Enregistré le: 22 Jan 2013, 16:20

par t.itou29 » 16 Avr 2014, 17:12

fatal_error a écrit:complètement subjectif.


j'ai pas non plus bcp d'expérience avec python, mais je peux au moins affirmer que c'est facile.
Toute ce que t'as à faire c'est de chercher un canvas, probablement tkinter, qui te propose une api, style plotCircle (pour faire des points) ou plotArc(angle 2PI) pour faire un cercle.
Généralement ces méthodes prennent en arguments x et y...donc tu devrais pas trop suer.

Merci, je vais chercher pour implémenter ces commandes dans mon programme. En fait l'intitulé exact est:
"n billes sont placées au hasard sur un cercle de rayon 1m, à chacune des billes est associée aléatoirement une direction (horaire / anti-horaire). Au temps t=0 les billes commencent à se déplacer à une vitesse constante de 2pi mètres par minute (dans la direction qui lui a été attribué) , si deux billes entrent en collision elles repartent dans la direction opposée à la même vitesse. On cherche à déterminer la position des billes au bout d'une minute."
Tant qu'à faire j'ai voulu déterminer la position au temps t, pour cela j'ai tenu compte seulement de l'angle.
Code: Tout sélectionner
# n angles au hasard #
# q: liste des angles #
# w: nbre de collisions #
n=int(input("billes"))
w=0
q=[0]
for i in range (1,n):
    x=float(random.uniform(0, 6.283))
    q.append(x)   
print(q)

# direction des billes #
# p: clockwise pour p=1 et anticlockwise pour p=-1 #
t=[-1,1]
p=[0]
for i in range (1,n):
    x=int(random.choice(t))
    p.append(x)
print(p)

# début mouvement #
for t in range (0,1000):
    for i in range (1,n):
        q[i]=q[i]+6.283*p[i]/1000
        if q[i]>=6.283:
           q[i]=q[i]-6.283
        if q[i]<0:
          q[i]=q[i]+6.283
# collisions #         
        for k in range (1,n):
            for s in range (1,n):
                    if abs(q[k]-q[s])<=0.005 and k<s:
# chgt direction #               
                      p[k]=-p[k]
                      p[s]=-p[s]
                      w=w+1
print(q)
print(w)
print(p)








Le problème c'est que le programme est pas très rapide et pas très précis. Il faudrait que j'implémente la commande pour afficher les billes entre #début mvt# et #collision# et les coordonnées seraient cos(q(i)) et sin(q(i)) ou y a-t-il plus simple ?

PS: pour avoir n billes il faut rentrer n+1 je vais modifier ça

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 17 Avr 2014, 08:26

Bonjour,

Code: Tout sélectionner
Le problème c'est que le programme est pas très rapide et pas très précis


C'est un peu le problème du python, c'est un langage simple à apprendre mais en cas de mauvaise optimisation il peut s'avérer beaucoup beaucoup plus lent que d'autres langages.

Maple est en effet très puissant pour réaliser ce que tu souhaites faire mais il y a des logiciels tout aussi puissant et opensource :

- http://maxima.sourceforge.net/

Il existe également d'autres logiciels qui je pense seront plus adapté à ce que tu souhaites faire :

- http://www.scilab.org/resources/documentation (en Fr)

- http://www.gnu.org/software/octave/ (en Eng)

Je pense qu'en utilisant un des deux logiciels tu devrais pouvoir obtenir un résultat plus que convenable, rapide et précis.

Iroh
Membre Relatif
Messages: 374
Enregistré le: 14 Oct 2008, 19:24

par Iroh » 17 Avr 2014, 11:59

Code: Tout sélectionner
import random
import matplotlib.pyplot as plt
from matplotlib import animation
from math import cos, sin

# init figure
fig = plt.figure()
ax = fig.add_subplot(111, xlim=(-2,2), ylim=(-2,2))
l, = ax.plot([], [], '.')
def init():
    l.set_data([], [])
    return l,



# n angles au hasard #
# q: liste des angles #
# w: nbre de collisions #
n=int(input("billes"))
w=0
q=[0]
for i in range (1,n):
    x=float(random.uniform(0, 6.283))
    q.append(x)
print(q)

# direction des billes #
# p: clockwise pour p=1 et anticlockwise pour p=-1 #
t=[-1,1]
p=[0]
for i in range (1,n):
    x=int(random.choice(t))
    p.append(x)
print(p)

# fonction principale animation
def animate_(t, q, p, w, l):
    for i in range (1,n):
        q[i]=q[i]+6.283*p[i]/1000
        if q[i]>=6.283:
           q[i]=q[i]-6.283
        if q[i]<0:
          q[i]=q[i]+6.283
        # collisions #
        for k in range (1,n):
            for s in range (1,n):
                if abs(q[k]-q[s])<=0.005 and k<s:
                    # chgt direction #
                    p[k]=-p[k]
                    p[s]=-p[s]
                    w=w+1
    # affiche points
    l.set_data([cos(q[i]) for i in xrange(n)],
               [sin(q[i]) for i in xrange(n)])
    return l,

def animate(t):
    return animate_(t, p, q, w, l)


anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=xrange(0, 1000),
                               interval=20, blit=True)

# anim.save('basic_animation.mp4', fps=30, codec='libx264')
plt.show()


J'ai juste rajouté une partie qui gère l'animation. Il te faut matplotlib.

Voir: http://videobin.org/+7o7/a4b.ogg

Il y a quelques problèmes, à toi de corriger.
Revois la fonction range. list(range(1,4)) = [1,2,3]
En python, l'indice des listes commence à zero.
Pourquoi avoir posé: q=[0] et pas q=[]?

Cliffe
Membre Rationnel
Messages: 967
Enregistré le: 12 Juin 2012, 13:25

par Cliffe » 17 Avr 2014, 15:39

avec maple : maple

t.itou29
Membre Rationnel
Messages: 601
Enregistré le: 22 Jan 2013, 16:20

par t.itou29 » 17 Avr 2014, 16:04

Iroh a écrit:
Code: Tout sélectionner
import random
import matplotlib.pyplot as plt
from matplotlib import animation
from math import cos, sin

# init figure
fig = plt.figure()
ax = fig.add_subplot(111, xlim=(-2,2), ylim=(-2,2))
l, = ax.plot([], [], '.')
def init():
    l.set_data([], [])
    return l,



# n angles au hasard #
# q: liste des angles #
# w: nbre de collisions #
n=int(input("billes"))
w=0
q=[0]
for i in range (1,n):
    x=float(random.uniform(0, 6.283))
    q.append(x)
print(q)

# direction des billes #
# p: clockwise pour p=1 et anticlockwise pour p=-1 #
t=[-1,1]
p=[0]
for i in range (1,n):
    x=int(random.choice(t))
    p.append(x)
print(p)

# fonction principale animation
def animate_(t, q, p, w, l):
    for i in range (1,n):
        q[i]=q[i]+6.283*p[i]/1000
        if q[i]>=6.283:
           q[i]=q[i]-6.283
        if q[i]<0:
          q[i]=q[i]+6.283
        # collisions #
        for k in range (1,n):
            for s in range (1,n):
                if abs(q[k]-q[s])<=0.005 and k<s:
                    # chgt direction #
                    p[k]=-p[k]
                    p[s]=-p[s]
                    w=w+1
    # affiche points
    l.set_data([cos(q[i]) for i in xrange(n)],
               [sin(q[i]) for i in xrange(n)])
    return l,

def animate(t):
    return animate_(t, p, q, w, l)


anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=xrange(0, 1000),
                               interval=20, blit=True)

anim.save('basic_animation.mp4', fps=30, codec='libx264')
plt.show()


J'ai juste rajouté une partie qui gère l'animation. Il te faut matplotlib.

Voir: http://videobin.org/+7nz/a3v.ogg

Il y a quelques problèmes, à toi de corriger.
Revois la fonction range. list(range(1,4)) = [1,2,3]
En python, l'indice des listes commence à zero.
Pourquoi avoir posé: q=[0] et pas q=[]?

Merci beaucoup ! C'est exactement ce que je voulais obtenir ! Quant à la la liste je pensais pas qu'on pouvait définir une liste vide, je vais modifier ça tout de suite. Et juste un détail, est-il possible de colorer les points ? Comme les points sont de la même couleur j'ai l'impression qu'il n'y a pas de collision. Encore merci :happy2:

t.itou29
Membre Rationnel
Messages: 601
Enregistré le: 22 Jan 2013, 16:20

par t.itou29 » 17 Avr 2014, 16:05

ampholyte a écrit:Bonjour,

Code: Tout sélectionner
Le problème c'est que le programme est pas très rapide et pas très précis


C'est un peu le problème du python, c'est un langage simple à apprendre mais en cas de mauvaise optimisation il peut s'avérer beaucoup beaucoup plus lent que d'autres langages.

Maple est en effet très puissant pour réaliser ce que tu souhaites faire mais il y a des logiciels tout aussi puissant et opensource :

- http://maxima.sourceforge.net/

Il existe également d'autres logiciels qui je pense seront plus adapté à ce que tu souhaites faire :

- http://www.scilab.org/resources/documentation (en Fr)

- http://www.gnu.org/software/octave/ (en Eng)

Je pense qu'en utilisant un des deux logiciels tu devrais pouvoir obtenir un résultat plus que convenable, rapide et précis.

Merci, je viens de télécharger scilab. Je vais tester !

Iroh
Membre Relatif
Messages: 374
Enregistré le: 14 Oct 2008, 19:24

par Iroh » 17 Avr 2014, 16:09

t.itou29 a écrit:Merci beaucoup ! C'est exactement ce que je voulais obtenir ! Quant à la la liste je pensais pas qu'on pouvait définir une liste vide, je vais modifier ça tout de suite. Et juste un détail, est-il possible de colorer les points ? Comme les points sont de la même couleur j'ai l'impression qu'il n'y a pas de collision. Encore merci :happy2:



Pour voir s'il y a une collision tu peux ajouter un print('coucou bob') après ta ligne qui teste la collision (if abs(q[k]-q[s])...).

(Tu utilises python2.X ou python3.X ?)

Iroh
Membre Relatif
Messages: 374
Enregistré le: 14 Oct 2008, 19:24

par Iroh » 17 Avr 2014, 16:46

Une autre, avec tkinter (sans avoir à installer de modules supplémentaires donc)

Code: Tout sélectionner
# -*- coding:utf-8 -*-

import random
from math import cos, sin



try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk
from itertools import count
def newpoint(master, x, y, *args):
    return master.create_rectangle(x*100, y*100, x*100, y*100, *args)
class Draw(tk.Canvas):
    def __init__(self, master):
        tk.Canvas.__init__(self, master, width=500, height=500, scrollregion=(-250, -250, 250, 250))
        self.pack(fill=tk.BOTH, expand=True)
        self.n = count()
        self.stop = False
    def animate(self, freq=20):
        if self.stop:
            return
        vx, vy = animate(next(self.n))
        self.delete(tk.ALL)
        for x, y in zip(vx, vy):
            newpoint(self, x, y)
        self.after(freq, self.animate, freq)
root = tk.Tk()
draw = Draw(root)



################################################################################
################################################################################
# n angles au hasard #
# q: liste des angles #
# w: nbre de collisions #
# freq: pause en milliseconde
n=int(input("billes"))
w=0
q=[0]
freq=20
for i in range (1,n):
    x=float(random.uniform(0, 6.283))
    q.append(x)
print(q)

# direction des billes #
# p: clockwise pour p=1 et anticlockwise pour p=-1 #
t=[-1,1]
p=[0]
for i in range (1,n):
    x=int(random.choice(t))
    p.append(x)
print(p)

# fonction principale animation
def animate_(t, q, p, w):
    for i in range (1,n):
        q[i]=q[i]+6.283*p[i]/1000
        if q[i]>=6.283:
           q[i]=q[i]-6.283
        if q[i]<0:
          q[i]=q[i]+6.283
        # collisions #
        for k in range (1,n):
            for s in range (1,n):
                if abs(q[k]-q[s])<=0.005 and k<s:
                    # chgt direction #
                    p[k]=-p[k]
                    p[s]=-p[s]
                    w=w+1
    # affiche points
    return ([cos(q[i]) for i in range(n)],
            [sin(q[i]) for i in range(n)])
################################################################################
################################################################################


def animate(t):
    return animate_(t, p, q, w)
draw.animate(freq)
draw.mainloop()



http://videobin.org/+7o7/a48.ogg

Cliffe
Membre Rationnel
Messages: 967
Enregistré le: 12 Juin 2012, 13:25

par Cliffe » 17 Avr 2014, 16:47

Vous vous compliquez la vie pour rien :ptdr:

Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 17 Avr 2014, 17:12

@Cliffe:
Vous vous compliquez la vie pour rien

1) Au cas où tu ne l'aurais pas encore remarqué, l'auteur de cette discussion veut faire des progrès en python. Pas C, pas C++, ni n'importe quel autre langage, mais python.
On a bien compris que tu aimes maple. Maintenant, c'est pas la peine d'insister autant. Une fois, deux fois pourquoi pas, après c'est lourd.

2) Une animation c'est bien mais si c'est pas reproduisible, c'est nul. Donc c'est clairement mieux d'avoir un code, compliqué ou pas que l'on peut regarder, utiliser, critiquer et améliorer qu'une vidéo dont on ne peut rien tirer.

3) Je me retiens de commentaires sur maple, mais comme cité ci-dessus, il y a plein d'alternatives mais quand quelqu'un veut apprendre le python c'est certainement pas pour faire en premier lieu des synergies avec du calcul formel.
la vie est une fête :)

Cliffe
Membre Rationnel
Messages: 967
Enregistré le: 12 Juin 2012, 13:25

par Cliffe » 17 Avr 2014, 17:20

Pk tu t'énerves ? Quest-ce qui t'arrive ??

fatal_error a écrit:@Cliffe:

1) Au cas où tu ne l'aurais pas encore remarqué, l'auteur de cette discussion veut faire des progrès en python. Pas C, pas C++, ni n'importe quel autre langage, mais python.


Si tu relis le problème initial, on essaye de modéliser un problème de mathématique et non pas de s'améliorer en programmation. Je persiste à dire que maple reste le plus approprié pour répondre aux besoin de titou.

fatal_error a écrit:@Cliffe:

2) Une animation c'est bien mais si c'est pas reproduisible, c'est nul. Donc c'est clairement mieux d'avoir un code, compliqué ou pas que l'on peut regarder, utiliser, critiquer et améliorer qu'une vidéo dont on ne peut rien tirer.


Il suffit de changer la valeur de n dans le programme et c'est reproductible ... Tu peux même faire une petite application avec interface graphique.

Cliffe
Membre Rationnel
Messages: 967
Enregistré le: 12 Juin 2012, 13:25

par Cliffe » 17 Avr 2014, 17:25


t.itou29
Membre Rationnel
Messages: 601
Enregistré le: 22 Jan 2013, 16:20

par t.itou29 » 17 Avr 2014, 19:00

Iroh a écrit:Une autre, avec tkinter (sans avoir à installer de modules supplémentaires donc)

Code: Tout sélectionner
# -*- coding:utf-8 -*-

import random
from math import cos, sin



try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk
from itertools import count
def newpoint(master, x, y, *args):
    return master.create_rectangle(x*100, y*100, x*100, y*100, *args)
class Draw(tk.Canvas):
    def __init__(self, master):
        tk.Canvas.__init__(self, master, width=500, height=500, scrollregion=(-250, -250, 250, 250))
        self.pack(fill=tk.BOTH, expand=True)
        self.n = count()
        self.stop = False
    def animate(self, freq=20):
        if self.stop:
            return
        vx, vy = animate(next(self.n))
        self.delete(tk.ALL)
        for x, y in zip(vx, vy):
            newpoint(self, x, y)
        self.after(freq, self.animate, freq)
root = tk.Tk()
draw = Draw(root)



################################################################################
################################################################################
# n angles au hasard #
# q: liste des angles #
# w: nbre de collisions #
# freq: pause en milliseconde
n=int(input("billes"))
w=0
q=[0]
freq=20
for i in range (1,n):
    x=float(random.uniform(0, 6.283))
    q.append(x)
print(q)

# direction des billes #
# p: clockwise pour p=1 et anticlockwise pour p=-1 #
t=[-1,1]
p=[0]
for i in range (1,n):
    x=int(random.choice(t))
    p.append(x)
print(p)

# fonction principale animation
def animate_(t, q, p, w):
    for i in range (1,n):
        q[i]=q[i]+6.283*p[i]/1000
        if q[i]>=6.283:
           q[i]=q[i]-6.283
        if q[i]<0:
          q[i]=q[i]+6.283
        # collisions #
        for k in range (1,n):
            for s in range (1,n):
                if abs(q[k]-q[s])<=0.005 and k<s:
                    # chgt direction #
                    p[k]=-p[k]
                    p[s]=-p[s]
                    w=w+1
    # affiche points
    return ([cos(q[i]) for i in range(n)],
            [sin(q[i]) for i in range(n)])
################################################################################
################################################################################


def animate(t):
    return animate_(t, p, q, w)
draw.animate(freq)
draw.mainloop()



http://videobin.org/+7o4/a40.ogg

ça tombe bien j'arrivais pas à installer matplolib (il n'est pas compatible avec python 3.4 je crois), par contre comment se fait-il que certaines billes vont plus vites que d'autres ?

Iroh
Membre Relatif
Messages: 374
Enregistré le: 14 Oct 2008, 19:24

par Iroh » 17 Avr 2014, 19:28

t.itou29 a écrit:ça tombe bien j'arrivais pas à installer matplolib (il n'est pas compatible avec python 3.4 je crois), par contre comment se fait-il que certaines billes vont plus vites que d'autres ?


Déso j'ai inversé p et q dans l'appel à la fonction animate_.

Code: Tout sélectionner
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import random
from math import cos, sin

import tkinter as tk

def random_dark_rgb(r=0.5):
    lighter = 0.5 * 255
    r = lambda: random.randint(0,255)
    def luminance(r, g, b):
        # https://en.wikipedia.org/wiki/Luminance_%28relative%29#Relative_luminance_in_colorimetric_spaces
        return 0.2126*r + 0.7152*g + 0.0722*b
    while True:
        rgb = r(), r(), r()
        if luminance(*rgb) =6.283:
           q[i]=q[i]-6.283
        if q[i]<0:
          q[i]=q[i]+6.283
        # collisions #
        for k in range (1,n):
            for s in range (1,n):
                if abs(q[k]-q[s])<=0.005 and k<s:
                    # chgt direction #
                    p[k]=-p[k]
                    p[s]=-p[s]
                    w=w+1
    # affiche points
    return ([cos(q[i]) for i in range(n)],
            [sin(q[i]) for i in range(n)])

root = tk.Tk()
draw = Draw(root, n, freq)
draw.animate()
draw.mainloop()



J'tai rajouté les couleurs.
http://videobin.org/+7o7/a47.ogg

En modifiant l'erreur dans la gestion des collisions, puis revoir range.
http://videobin.org/+7o7/a46.ogg


Python 3.4 est sorti il y a peu, tu peux installer le 3.2 plutôt (ou 3.3).

t.itou29
Membre Rationnel
Messages: 601
Enregistré le: 22 Jan 2013, 16:20

par t.itou29 » 19 Avr 2014, 14:19

Iroh a écrit:Déso j'ai inversé p et q dans l'appel à la fonction animate_.

Code: Tout sélectionner
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import random
from math import cos, sin

import tkinter as tk

def random_dark_rgb(r=0.5):
    lighter = 0.5 * 255
    r = lambda: random.randint(0,255)
    def luminance(r, g, b):
        # https://en.wikipedia.org/wiki/Luminance_%28relative%29#Relative_luminance_in_colorimetric_spaces
        return 0.2126*r + 0.7152*g + 0.0722*b
    while True:
        rgb = r(), r(), r()
        if luminance(*rgb) =6.283:
           q[i]=q[i]-6.283
        if q[i]<0:
          q[i]=q[i]+6.283
        # collisions #
        for k in range (1,n):
            for s in range (1,n):
                if abs(q[k]-q[s])<=0.005 and k<s:
                    # chgt direction #
                    p[k]=-p[k]
                    p[s]=-p[s]
                    w=w+1
    # affiche points
    return ([cos(q[i]) for i in range(n)],
            [sin(q[i]) for i in range(n)])

root = tk.Tk()
draw = Draw(root, n, freq)
draw.animate()
draw.mainloop()



J'tai rajouté les couleurs.
http://videobin.org/+7o7/a47.ogg

En modifiant l'erreur dans la gestion des collisions, puis revoir range.
http://videobin.org/+7o7/a46.ogg


Python 3.4 est sorti il y a peu, tu peux installer le 3.2 plutôt (ou 3.3).

Merci, je vais essayer de corriger l'erreur pour les collisions.

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité

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