Exemples en Python
Exemple 1
Una càmera sensa el perfil d'una sèrie d'objectes que passen per una banda transportadora. Els perfils són captats com una poligonal simple i tancada.
Una poligonal és una seqüència de punts del pla \((p_0, p_1, \dots, p_k)\) que representa una seqüència de segments \( ([p_0,p_1], [p_1,p_2], \dots [p_k,p_0]) \) cap dels quals s'intersecta amb cap altre. Per a que una poligonal tingui sentit cal que la seqüència tingui com a mínim 3 punts.
Es vol construïr un programa que llegeix una sèrie de perfils i determina quants son dins d'un cercle de radi 1 i centrat en l'orígen. Assumeix que la seqüència de polígonals s'acaba amb una poligonal buida, és a dir sense cap punt. El format de la seqüència de poligonals és com el del següent exemple:
(x0,y0) (x1,y1) (xn,yn), () (x0,y0), ..., (xk,yk), () ()
Noteu que cada poligonal acaba sempre amb un punt buit () i que la poligonal buida (sense punts) actua de sentinella.
Solució
El primer que farem és implementar una classe Punt per representar un punt en el pla. Aquest punt serà després el component principal de les poligonals:
Afegirem també una classe que representi cercles arbitraris en el pla. La seva representació contindrà un Punt (el centre) i un radi. A més Hi afegirem una operació que permeti saber si un Punt donat és dins o fora del cercle. Noteu que això passa si la distància entre el centre i el punt és menor que el radi:
Començarem implementant una classe que representi les poligonals. Cada poligonal la representarem com una llista de punts. Dotarem la classe de modificadors que permetin afegir nous punts a la poligonal, de la funció len que permetrà saber el nombre de punts de la poligonal i també d'una classe que permeti comprovar si una poligonal es troba completament inclosa en un cercle.
En base a aquestes classes podem escriure ara un programa principal que resol l'enunciat simplement llegint la seqüència de poligonals. Per llegir la seqüència de poligonals podem usar unes funcions auxiliars:
1 def llegir_punt():
2 """
3 Retorna un Punt o None si no hi ha més punts.
4 """
5 s = raw_input().strip().strip('()')
6 if s :
7 punts = s.split(',')
8 return Punt(float(punts[0]), float(punts[1]))
9 else:
10 return None
11
12 def llegir_poligonal():
13 """
14 Retorna una poligonal o None
15 """
16 p = llegir_punt()
17 if p is None:
18 return None
19 else:
20 poli = Poligonal()
21 while p is not None:
22 p.add(poli)
23 p = llegir_punt()
24 return poli
A partir d'aquí, crear una funció que compti les poligonals incloses en el cercle unitat és pot fer així:
Amb tot això, el programa complet escrit en un únic mòdul és el següent:
1 # -*- encoding: utf-8 -*-
2
3 from math import sqrt
4
5
6 class Punt(object):
7
8 def __init__(self, x=0.0, y=0.0):
9 self.x = x
10 self.y = y
11
12 def dist(self,p):
13 """
14 Distància entre dos punts.
15 """
16 return sqrt((self.x - p.x) ** 2 + (self.y - p.y) ** 2)
17
18
19 class Cercle(object):
20
21 def __init__(self, c = Punt(), r=1.0):
22 self.c = c
23 self.r = r
24
25 def dins(self, p):
26 return self.c.dist(p) < self.r
27
28
29 class Poligonal(object):
30
31 def __init__(self):
32 self.lp = []
33
34 def add(self, p):
35 self.lp.append(p)
36
37 def __len__(self):
38 return len(self.lp)
39
40 def dins(self,c):
41 return all([c.dins(p) for p in self.lp])
42
43
44 def llegir_punt():
45 """
46 Retorna un Punt o None si no hi ha més punts.
47 """
48 s = raw_input().strip().strip('()')
49 if s :
50 punts = s.split(',')
51 return Punt(float(punts[0]), float(punts[1]))
52 else:
53 return None
54
55 string
56 def llegir_poligonal():
57 """
58 Retorna una poligonal o None
59 """
60 p = llegir_punt()
61 if p is None:
62 return None
63 else:
64 poli = Poligonal()
65 while p is not None:
66 p.add(poli)
67 r = llegir_punt()
68 return poli
69
70
71 def compta_incloses():
72 n = 0
73 cu = Cercle()
74 p = llegir_poligonal()
75 while p is not None:
76 if p.dins(cu):
77 n += 1
78 return n
79
80
81 if __name__ == '__main__':
82 print compta_incloses()