Exercice 0

On se propose de travailler avec des coordonnées polaires, c'est-à-dire avec des points dans un plan défini par un couple (r,\theta) avec r la distance par rapport à l'origine d'un repère du plan et \theta l'angle, en degrés) entre l'axe x'Ox et le point considéré.

Question: écrire une classe Polaire qui permet d'utiliser le script principal suivant:

#!/usr/bin/env python

# importation de la classe Polaire depuis Polaire.py
from Polaire import Polaire

# creation de deux points par des coordonnes polaires
P1 = Polaire(2.0,0.0)   # R = 2.0, Theta =  0.0 degrees
P2 = Polaire(2.0, 90.0) # R = 2.0, Theta = 90.0 degrees

print "P1 = %r" % (P1)
print "P2 = %r" % (P2)
print
x1, y1 = P1.xy
r1, theta1 = P1.value
x2, y2 = P2.xy
r2, theta2 = P2.value
print "P1 x = %f y = %f r = %f theta = %f" % (x1, y1, r1, theta1)
print "P2 x = %f y = %f r = %f theta = %f" % (x2, y2, r2, theta2)
print
print "distance entre P1 et P2 = %f" % (Polaire.distance(P1,P2))
print

P3 = Polaire(3,30.)
print "P3 = %r" % (P3)
print "Symetrie X de P3 = %r" % (P3.symetrieX())
print "Symetrie Y de P3 = %r" % (P3.symetrieY())
P4 = Polaire(3,120.)
print "P4 = %r" % (P4)
print "Symetrie X de P4 = %r" % (P4.symetrieX())
print "Symetrie Y de P4 = %r" % (P4.symetrieY())

qui donne le résultat suivant à l'exécution:

P1 = (2.000000,0.000000)
P2 = (2.000000,90.000000)

P1 x = 2.000000 y = 0.000000 r = 2.000000 theta = 0.000000
P2 x = 0.000000 y = 2.000000 r = 2.000000 theta = 90.000000

distance entre P1 et P2 = 2.828427

P3 = (3.000000,30.000000)
Symetrie X de P3 = (3.000000,-30.000000)
Symetrie Y de P3 = (3.000000,150.000000)
P4 = (3.000000,120.000000)
Symetrie X de P4 = (3.000000,-120.000000)
Symetrie Y de P4 = (3.000000,60.000000)

Réponse

L'idée est de travailler non pas en coordonnées polaires, mais en coordonnées cartésiennes (plus simple par exemple pour calculer des distances entre points), tout en recalculant automatiquement les coordonnées polaires r et theta quand on en a besoin.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import math

class Polaire(object):
  """Cette classe traite des coordonnes polaires (r,theta) avec r > 0 et theta un angle en degrees"""
  __slots__ = ["__x", "__y"] # on ne garde que les coordonnees cartesiennes
  def __init__(self, r = 0., theta = 0.):
    """Constructeur de la classe, prends un r (positif) et un theta en argument"""
    if r < 0.:
      raise ValueError("r must be positive. Here r = %r" % (r))
    angle = theta/180.0*math.pi # conversion en radians
    self.__x = r*math.cos(angle)
    self.__y = r*math.sin(angle)

  def __repr__(self):
    """represente des coordonnees polaires par un couple (r,theta)"""
    return "(%f,%f)" % (self.__r, self.__theta)

  def __getr(self):
    return math.sqrt(self.__x*self.__x+self.__y*self.__y)
  __r = property(__getr)

  def __gettheta(self):
    angle = math.acos(self.__x/self.__r)
    if self.__y < 0:
      angle = -angle
    return angle/math.pi*180.0                                                                                                        
  __theta = property(__gettheta)

  def __getvalue(self):
    return self.__r, self.__theta
  value = property(__getvalue, doc="""value retourne le couple (r,theta). Il n'y a pas de mutateur associe.""")

  def __getxy(self):
    return self.__x, self.__y
  xy = property(__getxy, doc="""xy retourne le couple (x,y) ou x et y sont les coordonnees cartesiennnes du point.
Il n'y a pas de mutateur associé""")

  def rtheta_from_xy(x, y):
    """retourne des coordonnes polaires a partir de coordonnes cartesiennes"""
    """la methode est privee car l'utilisateur ne voit que les coordonnees polaires"""
    r = math.sqrt(x*x+y*y)
    theta = math.acos(x/r)
    if y < 0:
      theta = - theta
    return r, theta/math.pi*180.0
  rtheta_from_xy = staticmethod(rtheta_from_xy)

  def symetrieX(self):
    """retourne le point Polaire symetrie de l'objet courant par rapport a l'axe des X"""
    x =  self.__x
    y = -self.__y
    r, theta = Polaire.rtheta_from_xy(x, y)
    return Polaire(r, theta)

  def symetrieY(self):
    """retourne le point Polaire symetrie de l'objet courant par rapport a l'axe des Y"""
    x = -self.__x
    y =  self.__y
    r, theta = Polaire.rtheta_from_xy(x, y)
    return Polaire(r, theta)

  def distance(P1, P2):
    """calcule la distance entre deux points Polaires P1 et P2"""
    dx = P1.__x-P2.__x
    dy = P1.__y-P2.__y
    return math.sqrt(dx*dx+dy*dy)
  distance = staticmethod(distance)