def rayon_couleur (self, rayon, ref = True) : """retourne la couleur d'un rayon connaissant les objets, cette fonction doit être surchargée pour chaque modèle d'illumination, si ref == True, on tient compte des rayons réfracté et réfléchi""" list_rayon = [ rayon ] c = base.couleur (0,0,0) b = False while len (list_rayon) > 0 : r = list_rayon.pop () o,p = self.intersection (r) if p == None : continue if ref : t = o.rayon_refracte (r, p) if t != None : list_rayon.append (t) t = o.rayon_reflechi (r, p) if t != None : list_rayon.append (t) sources = self.sources_atteintes (p) if len (sources) == 0 : return base.couleur (0,0,0) for s in sources : cl = self.modele_illumination (r, p, o, s) c += cl b = True if not b : c = self.couleur_fond () else : c.borne () return c
def construit_rayon (self, pixel) : """construit le rayon correspondant au pixel pixel""" x = (pixel.x - self.dim [0] / 2) * math.tan (self.alpha / 2) / min (self.dim) y = (pixel.y - self.dim [1] / 2) * math.tan (self.alpha / 2) / min (self.dim) v = base.vecteur (x,y,1) r = base.rayon (self.repere.origine, self.repere.coordonnees (v), \ pixel, base.couleur (1,1,1)) return r
def __init__(self, a, b, c, d, nom_image, invertx=False): """initialisation, si d == None, d est calculé comme étant le symétrique de b par rapport au milieu du segment [ac], la texture est une image, si invertx == True, inverse l'image selon l'axe des x""" facette.rectangle.__init__(self, a, b, c, d, base.couleur(0, 0, 0)) self.image = pygame.image.load(nom_image) self.nom_image = nom_image self.invertx = invertx
def __init__(self, a,b,c,d, nom_image, invertx = False): """initialisation, si d == None, d est calculé comme étant le symétrique de b par rapport au milieu du segment [ac], la texture est une image, si invertx == True, inverse l'image selon l'axe des x""" facette.rectangle.__init__(self, a,b,c,d, base.couleur (0,0,0)) self.image = pygame.image.load (nom_image) self.nom_image = nom_image self.invertx = invertx
def __init__ (self, repere, alpha, x,y, ka = 0.1, kb = 0.8, kc = 0.3, reflet = 6, fond = base.couleur (200,200,200)) : """définit la position de l'oeil, l'angle d'ouverture, et la taille de l'écran""" scene.scene.__init__ (self, repere, alpha, x, y) self.ka, self.kb, self.kc = ka,kb,kc self.reflet = reflet self.fond = fond self.constante = float (1)
def couleur_point (self, p) : """retourne la couleur au point de coordonnée p""" ap = p - self.a ab = self.b - self.a ad = self.d - self.a abn = ab.norme2 () adn = ad.norme2 () x = ab.scalaire (ap) / abn y = ad.scalaire (ap) / adn sx,sy = self.image.get_size () k,l = int (x * sx), int (y * sy) k = min (k, sx-1) l = min (l, sy-1) l = sy - l - 1 if not self.invertx : c = self.image.get_at ((k,l)) else : c = self.image.get_at ((sx-k-1,l)) cl = base.couleur (float (c [0]) / 255, float (c [1]) / 255, float (c [2]) / 255) return cl
def couleur_point(self, p): """retourne la couleur au point de coordonnée p""" ap = p - self.a ab = self.b - self.a ad = self.d - self.a abn = ab.norme2() adn = ad.norme2() x = ab.scalaire(ap) / abn y = ad.scalaire(ap) / adn sx, sy = self.image.get_size() k, l = int(x * sx), int(y * sy) k = min(k, sx - 1) l = min(l, sy - 1) l = sy - l - 1 if not self.invertx: c = self.image.get_at((k, l)) else: c = self.image.get_at((sx - k - 1, l)) cl = base.couleur( float(c[0]) / 255, float(c[1]) / 255, float(c[2]) / 255) return cl
n = self.normale(p, rayon) n = n.renorme() y = n.scalaire(rayon.direction) d = rayon.direction - n * y * 2 r = base.rayon(p, d, rayon.pixel, rayon.couleur * self.reflet) return r if __name__ == "__main__": psyco.full() s = scene.scene_phong(base.repere(), math.pi / 1.5, 400, 200) s.ajoute_source ( base.source (base.vecteur (0,8,8), \ base.couleur (0.4,0.4,0.4) ) ) s.ajoute_source ( base.source (base.vecteur (10,0,0), \ base.couleur (0.4,0.4,0.4) ) ) s.ajoute_source ( base.source (base.vecteur (8,8,4.5), \ base.couleur (0.4,0.4,0.4) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (3,-4,7), \ 1, base.couleur (1,0,0) ) ) s.ajoute_objet ( sphere_reflet (base.vecteur (0,-400,12), \ 396, base.couleur (0.5,0.5,0.5), 0.5 ) ) s.ajoute_objet (rectangle_image ( base.vecteur (8,-3.5,9), \ base.vecteur (2,-3.5,8), \ base.vecteur (2,3.8,8), \ None, \ "bette_davis.png", invertx = True))
n = self.normale (p, rayon) n = n.renorme () y = n.scalaire (rayon.direction) d = rayon.direction - n * y * 2 r = base.rayon (p, d, rayon.pixel, rayon.couleur * self.reflet) return r if __name__ == "__main__" : psyco.full () s = scene.scene_phong (base.repere (), math.pi / 1.5, 400, 200) s.ajoute_source ( base.source (base.vecteur (0,8,8), \ base.couleur (0.4,0.4,0.4) ) ) s.ajoute_source ( base.source (base.vecteur (10,0,0), \ base.couleur (0.4,0.4,0.4) ) ) s.ajoute_source ( base.source (base.vecteur (8,8,4.5), \ base.couleur (0.4,0.4,0.4) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (3,-4,7), \ 1, base.couleur (1,0,0) ) ) s.ajoute_objet ( sphere_reflet (base.vecteur (0,-400,12), \ 396, base.couleur (0.5,0.5,0.5), 0.5 ) ) s.ajoute_objet (rectangle_image ( base.vecteur (8,-3.5,9), \ base.vecteur (2,-3.5,8), \ base.vecteur (2,3.8,8), \ None, \ "bette_davis.png", invertx = True))
def __str__(self): """affichage""" s = "rectangle --- a : " + str(self.a) s += " b : " + str(self.b) s += " c : " + str(self.c) s += " d : " + str(self.d) s += " couleur : " + str(self.couleur) return s if __name__ == "__main__": s = scene.scene_phong(base.repere(), math.pi / 1.5, 400, 300) s.ajoute_source ( base.source (base.vecteur (0,8,8), \ base.couleur (0.6,0.6,0.6) ) ) s.ajoute_source ( base.source (base.vecteur (10,0,0), \ base.couleur (0.6,0.6,0.6) ) ) s.ajoute_source ( base.source (base.vecteur (8,8,4.5), \ base.couleur (0.6,0.6,0.6) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (1,0,5), \ 1, base.couleur (1,0,0) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,-400,12), \ 396, base.couleur (0.5,0.5,0.5) ) ) s.ajoute_objet (facette ( base.vecteur (0,-2.5,6), \ base.vecteur (-2,-2.5,3), \ base.vecteur (1,-3.5,4.5), \ base.couleur (0.2,0.8,0))) s.ajoute_objet (rectangle ( base.vecteur (0,-2.5,6), \ base.vecteur (-2,-2.5,3), \ base.vecteur (-2,2.8,3.5), \
s += " b : " + str (self.b) s += " c : " + str (self.c) s += " d : " + str (self.d) s += " couleur : " + str (self.couleur) return s if __name__ == "__main__" : s = scene.scene_phong (base.repere (), math.pi / 1.5, 400, 300) s.ajoute_source ( base.source (base.vecteur (0,8,8), \ base.couleur (0.6,0.6,0.6) ) ) s.ajoute_source ( base.source (base.vecteur (10,0,0), \ base.couleur (0.6,0.6,0.6) ) ) s.ajoute_source ( base.source (base.vecteur (8,8,4.5), \ base.couleur (0.6,0.6,0.6) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (1,0,5), \ 1, base.couleur (1,0,0) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,-400,12), \ 396, base.couleur (0.5,0.5,0.5) ) ) s.ajoute_objet (facette ( base.vecteur (0,-2.5,6), \ base.vecteur (-2,-2.5,3), \ base.vecteur (1,-3.5,4.5), \ base.couleur (0.2,0.8,0))) s.ajoute_objet (rectangle ( base.vecteur (0,-2.5,6), \ base.vecteur (-2,-2.5,3), \ base.vecteur (-2,2.8,3.5), \
cos = n.scalaire (vs) couleur = source.couleur.produit_terme (obj.couleur_point (p)) * (cos * self.kb) # second terme : reflet cos = n.scalaire (bi) ** self.reflet couleur += source.couleur.produit_terme (source.couleur) * (cos * self.kc) couleur = couleur.produit_terme (rayon.couleur) return couleur if __name__ == "__main__" : s = scene_phong (base.repere (), math.pi / 1.5, 400, 300) s.ajoute_source ( base.source (base.vecteur (0,10,10), \ base.couleur (1,1,1) ) ) s.ajoute_source ( base.source (base.vecteur (10,10,5), \ base.couleur (0.5,0.5,0.5) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,0,12), \ 3, base.couleur (1,0,0) ) ) s.ajoute_objet ( obj.sphere (base.vecteur (0,-400,12), \ 396, base.couleur (0.5,0.5,0.5) ) ) print s screen = pygame.display.set_mode (s.dim) screen.fill ((255,255,255)) s.construit_image (screen) print "image terminée" scene.attendre_clic ()
return v def normale (self, p, rayon) : """retourne la normale au point de coordonnée p""" v = (p - self.centre) / self.rayon return v def couleur_point (self, p) : """retourne la couleur au point de coordonnée p""" return self.couleur def __str__ (self): """affichage""" s = "sphère --- centre : " + str (self.centre) s += " rayon : " + str (self.rayon) s += " couleur : " + str (self.couleur) return s if __name__ == "__main__" : s = sphere (base.vecteur (0,0,0), 5, base.couleur (0,1,0)) r = base.rayon ( base.vecteur (10,0,0), base.vecteur (1,0,0), \ base.pixel (0,0), base.couleur (0,0,0)) print (s) print (r) p = s.intersection (r) print (p)
def couleur_fond (self) : """retourne la couleur du fond""" return base.couleur (0,0,0)
if l == None: return None v = r.origine + r.direction * l return v def normale(self, p, rayon): """retourne la normale au point de coordonnée p""" v = (p - self.centre) / self.rayon return v def couleur_point(self, p): """retourne la couleur au point de coordonnée p""" return self.couleur def __str__(self): """affichage""" s = "sphère --- centre : " + str(self.centre) s += " rayon : " + str(self.rayon) s += " couleur : " + str(self.couleur) return s if __name__ == "__main__": s = sphere(base.vecteur(0, 0, 0), 5, base.couleur(0, 1, 0)) r = base.rayon ( base.vecteur (10,0,0), base.vecteur (1,0,0), \ base.pixel (0,0), base.couleur (0,0,0)) print(s) print(r) p = s.intersection(r) print(p)