Table des matières Python

Module python pyDraw

1. Principe

Le module python pyDraw permet de générer un dessin vectoriel en Python. Les éléments XML sont définis dans les pages Dessin vectoriel : fonctions de base et Dessin vectoriel : formes d'usage général. À chaque élément XML correspond une classe Python. Le premier argument du constructeur est la liste des attributs sous forme de dictionnaire. Les attributs de taille et de position sont fournis sous forme numérique, en particulier lorsqu'ils sont regroupés en liste. Lorsque l'élément contient du texte, celui-ci est fourni en deuxième argument du constructeur. La méthode de classe add permet d'ajouter un élément fils. La méthode de classe serialize renvoit la représentation textuelle de l'élément XML correspondant.

Dans l'exemple suivant, les différents éléments de la figure sont ajoutés à un objet de la classe Draw.

import pyDraw as d
draw = d.Draw({'name':'figureA','width':400,'height':300,'pdf-scale':0.5})
draw.add(d.Line({'x1':0,'y1':0,'x2':400,'y2':300,'stroke':'red'}))
draw.add(d.Text({'x':50,'y':50,'a':'t'},"bonjour"))
draw.add(d.Polyline({'points':[[0,0],[200,0],[200,100],[100,100]],'stroke':'blue','fill':'none'}))
path=d.Path({'stroke':'red','fill':'gray','stroke-width':2})
path.moveto([200,200])
path.lineto([200,230])
path.lineto([170,230]) 
path.curveto([[150,230],[140,230],[110,200]])
path.closepath()
draw.add(path)
g = d.Group({'stroke':'green','fill':'none'})
g.add(d.Line({'x1':20,'y1':50,'x2':20,'y2':100}))
draw.add(g)
t=d.Translate({'tx':300,'ty':200})
t.add(d.Rect({'x':0,'y':0,'width':20,'height':10,'stroke':'red','fill':'yellow'}))
t.add(d.Circle({'cx':30,'cy':30,'r':10,'stroke':'blue','fill':'yellow'}))
a = d.Arrow({'x1':0,'y1':0,'x2':70,'y2':-10,'start':'none','end':'arrowB','stroke':'black','scale':5})
a.add(d.Legend({'pos':'middle','a':'t'},'v'))
t.add(a)   
draw.add(t)
draw.add(d.Vlines({'x':[20,30,40,50,60],'y1':200,'y2':300,'stroke':'brown'}))
draw.add(d.Dtex({'x':200,'y':100,'a':'l','stroke':'black','fill':'black'},"$$f(x)=\\int_0^x\\sqrt{1+u(t)}\,dt$$"))
            

La figure est insérée dans la page avec le fragement XML suivant :

<python type="xml">draw.serialize()</python>

Elle apparaît dans la page HTML sous forme de figure SVG. Dans le document PDF, la figure est incluse sous forme vectorielle, avec une mise en forme du texte par TeX.

figureA.svgFigure pleine page

2. Ajout d'objets

Le module pyDraw permet d'ajouter facilement de nouveaux objets graphiques, construits à partir des formes élémentaires. L'exemple suivant définit une classe (dérivée de la classe pyDraw.Group) qui permet de tracer un zigzag, utile par exemple pour représenter un ressort.

import math 
class Zigzag(d.Group): 
    def __init__(self,att):
        x1 = att['x1']
        y1 = att['y1']
        x2 = att['x2']
        y2 = att['y2']
        width = att['width']
        number = att['number']
        end = att['end']
        length = math.sqrt((x2-x1)**2+(y2-y1)**2)
        cos = (x2-x1)/length
        sin = (y2-y1)/length
        att['fill'] = 'none'
        d.Group.__init__(self,att)
        translate = d.Translate({'tx':x1,'ty':y1})
        self.add(translate)
        transform = d.Matrix({'m':[cos,sin,-sin,cos,0,0]})
        translate.add(transform)
        path = d.Path({})
        path.moveto([0,0])
        path.lineto([end,0])
        dx = (length-2*end)/number
        for i in range(number):
            path.lineto([end+(i+0.25)*dx,width/2])
            path.lineto([end+(i+0.75)*dx,-width/2])
            path.lineto([end+(i+1.0)*dx,0])
        path.lineto([length,0])
        transform.add(path) 
     
            

Exemple d'utilisation :

draw = d.Draw({'name':'figureB','width':200,'height':300,'pdf-scale':0.5})
draw.add(Zigzag({'x1':100,'y1':100,'x2':200,'y2':150,'width':10,'number':10,'end':10,'stroke':'black','stroke-width':1.5}))
            
figureB.svgFigure pleine page

La classe Zigzag fait partie des objets supplémentaires ajoutés dans le module pyDraw et présentés ci-dessous.

3. Objets supplémentaires

Ces objets sont dans le module pyDraw.

4. Module pyDrawElectro

Ce module encapsule les éléments XML définis dans Dessin vectoriel : circuits électriques et définit d'autres objets plus complexes.

La position d'un composant peut être donnée par l'attribut pos à la place des attributs x et y. Chaque composant possède un attribut bornes qui contient la liste des bornes. Cela permet de placer un composant sur une des bornes d'un autre composant.

L'exemple suivant montre l'insertion de composants électriques élémentaires. La figure est composée à la fois à partir d'éléments XML et d'objets python.

L'objet Fil permet de connecter deux bornes par un fil, constitué d'un ou deux segments. Les attributs b1 et b2 précisent les deux bornes à relier. L'attribut dir indique la direction du premier segment lorsque les deux bornes n'ont aucune coordonnée en commun (h ou v, valeur par défaut h). Les attributs p1 et p2 (facultatifs) indiquent la présence de pastilles aux extrémités, en donnant leur couleur.

 
import pyDrawElectro as el
E = el.Vsource({'pos':[0,0],'orient':'u','legend':'E'})
R1 = el.Resistance({'pos':E.bornes[1],'orient':'r','legend':'R1'})
C1 = el.Capacite({'pos':R1.bornes[1],'orient':'r','legend':'C1'})
L1 = el.Inductance({'pos':C1.bornes[1],'orient':'d','legend':'L1'})
M = el.Masse({'pos':E.bornes[0],'orient':'d'})
circuit = d.Group({'stroke':'black'})
circuit.add([E,R1,C1,L1,M])
circuit.add(el.Fil({'b1':E.bornes[0],'b2':L1.bornes[1],'stroke':'black','p1':'black'}))
            
<draw name="figureC" width="400" height="300" medium-font-size="10" pdf-scale="0.7" stroke="black" fill="none" stroke-linecap="round">
    <rect x="1" y="1" width="399" height="299" stroke="grey"/>
    <translate tx="100" ty="100">
        <scale sx="40" sy="40">
            <python type="xml">circuit.serialize()</python>
        </scale>
    </translate> 
</draw>             
            
figureC.svgFigure pleine page

L'exemple suivant comporte un amplificateur différentiel et un transistor bipolaire. Pour les composants à au moins 3 bornes, celles-ci sont numérotées dans le sens horaire.

 
ao = el.Ampli({'pos':[0,0],'orient':'r','pol':'-','stroke':'red','vp':'+15V','vm':'-15V'}) 
R1 = el.Resistance({'pos':ao.bornes[0],'orient':'l','legend':'R1'})
R2 = el.Resistance({'pos':[0,-2],'orient':'r','legend':'R2'})
C1 = el.Capacite({'pos':ao.bornes[1],'orient':'u','legend':'C1'})
Q1 = el.Bipolaire({'pos':ao.bornes[2],'orient':'r','type':'npn','pol':'+','legend':'Q1','stroke':'blue'})
R3 = el.Resistance({'pos':Q1.bornes[2],'orient':'d','legend':'R3'})
R4 = el.Resistance({'pos':Q1.bornes[1],'orient':'u','legend':'R4'})
circuit = d.Group({'stroke':'black'}) 
circuit.add([ao,R1,R2,C1,Q1,R3,R4])
circuit.add(el.Fil({'b1':R1.bornes[0],'b2':R2.bornes[0],'p1':'black'}))
circuit.add(el.Fil({'b1':R2.bornes[1],'b2':ao.bornes[2],'p2':'black'}))
            
figureD.svgFigure pleine page

Connexion et circuits intégrés :

c1 = el.Connexion({'pos':[0,0],'orient':'r','name':'A0','number':0,'fill':'black'})
c2 = el.Connexion({'pos':[0,0.5],'orient':'r','name':'A1','number':1,'fill':'black'})
ci = el.CircuitIntegre({'pos':[2,0],'nw':3,'nh':4,'name':'NOM','stroke':'blue','legend-fill':'red'})
ci.connexion({'side':'r','name':'A0','number':0})
ci.connexion({'side':'r','name':'A1','number':1})
ci.connexion({'side':'r','name':'null'})
ci.connexion({'side':'r','name':'A2','number':2})
ci.connexion({'side':'l','name':'A3','number':3})
ci.connexion({'side':'t','name':'A4','number':4})
ci.connexion({'side':'b','name':'A5','number':5})
R = el.Resistance({'pos':ci.bornes[2],'orient':'r','legend':'R'})
circuit = d.Group({'stroke':'black'}) 
circuit.add([c1,c2,ci,R])    
            

Le point de positionnement du circuit intégré est le coin inférieur gauche. Les bornes sont espacées de 1/2. Le dictionnaire bornes permet d'accéder aux positions des bornes.

figureE.svgFigure pleine page

Le module comporte des circuits intégrés prédéfinis comme le suivant :

import pyDrawElectroCI as ci
ao = ci.Ampli8b({'pos':[0,0],'name':'TL081'})
p1 =el.Piste({'b1':ao.bornes[6],'b2':[8,2],'path':[['r',2],['d',2],['r',2]],'dir':'v'})
circuit = d.Group({'stroke':'black'}) 
circuit.add([ao,p1])     
            
figureF.svgFigure pleine page

L'objet Piste permet de relier deux points en suivant un chemin quelconque. Le chemin est donné par l'attribut path sous forme d'une liste de segments, chacun étant défini par une direction (r,l,u ou d) et une longueur. Les deux derniers segments n'ont pas à être définis. L'attribut dir indique la direction de l'avant dernier segment (h ou v). Si l'attribut path est absent, la piste comporte seulement deux segments.

Creative Commons LicenseTextes et figures sont mis à disposition sous contrat Creative Commons.