#include #include #include "projet.h" /* on inclut le fichier de déclaration des classes */ class Couleur; class RGB; class Image; class point3d; class vecteur3d; class rayon; class sphere; class source; class maillon; class listesol; int n=150; /* n correspond au nombre le lignes divisé par 3 et de colonnes divisé par 4 (format 4/3 de l'image) de l'image finale on le place ici pour permettre à toutes les methodes d'y avoir acces */ /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ CLASSE COULEUR @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ // CONSTRUCTEUR DE LA CLASSE COULEUR Couleur :: Couleur (unsigned int rot, unsigned int grun, unsigned int blau) { red=rot; green=grun; blue=blau; }; /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ CLASSE RGB @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ // CONSTRUCTEUR DE LA CLASSE RGB RGB :: RGB ( double red, double green, double blue) { r = red; g = green; b = blue; }; // METHODE DE LA CLASSE RGB //METHODES GET double RGB:: getr(){ return r; }; double RGB:: getg(){ return g; }; double RGB:: getb(){ return b; }; //METHODE SOMME RGB somme(RGB a,RGB c){ /* cette méthode somme deux couleurs */ RGB aux; /* on créer une couleur temporaire qui va etre retournée à la fin de la méthode */ if( a.getr()+c.getr()<=1){ /* on affecte à la composante rouge de la couleur temporaire soit la somme des composantes rouges */ aux.r=a.getr()+c.getr(); /* des deux couleurs a et c si cette somme est inférieure ou égale à 1 ou si elle est supérieure */ } /* on retourne 1 (saturation)*/ else aux.r=1; if( a.getg()+c.getg()<=1){ /* on fait de même avec les composantes verte et bleue */ aux.g=a.getg()+c.getg(); } else aux.g=1; if( a.getb()+c.getb()<=1){ aux.b=a.getb()+c.getb(); } else aux.b=1; return aux; /* on retourne la couleur temporaire en sortie , cette couleur étant la couleur somme des deux paramètres*/ }; //METHODE MUL RGB mul(double a,RGB b){ /* cette méthode multiplie l'intensité d'une couleur par un coefficient*/ RGB aux; /* comme pour la méthode précedente on créer une couleur temporaire */ if((a*0.5*b.getr())<=1){ /*on multiplie les composantes vertes rouges et bleu de la lumière paramètre par le coefficient a*/ aux.r=(a*0.5*b.getr()); /* on pondère cette multiplication par 1/2 pour éviter une saturation trop rapide de chaque */ } /* composantes */ else aux.r=1; if((b.getb()*0.5*a)<=1){ aux.b=(a*0.5*b.getb()); } else aux.b=1; if((a*0.5*b.getg())<=1){ aux.g=(a*0.5*b.getg()); } else aux.g=1; return aux; /* on retourne la couleur temporaire en sortie, cette couleur étant la couleur d'entrée multipliée par la paramatre a */ }; //METHODE CONVERTIR Couleur RGB :: convertir () /* cette methode convertit une couleur RGB en couleur Couleur */ { unsigned short r1,g1,b1; /* on multiplie tout simplement chaque composante par 255 */ r1= (unsigned short) floor(255*r); g1= (unsigned short) floor(255*g); b1= (unsigned short) floor(255*b); Couleur col (r1,g1,b1); return col; }; /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ CLASSE IMAGE @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ //METHODES DE LA CLASSE IMAGE Image :: Image ( int nbLignes, int nbColonnes){ nbLig = nbLignes; nbCol = nbColonnes; pixel = new Couleur [nbCol * nbLig]; }; void Image :: save (char nomFichier []) { ofstream outFile ; outFile.open(nomFichier, ios::out); outFile << "P3"<=0)&&(i=0)&&(j=0){ double aux1,aux2,n1,n2; aux1=(((-2*(prodscal(CA,u)))+sqrt(delta))/2); aux2=(((-2*(prodscal(CA,u)))-sqrt(delta))/2); b1.x=(((u.x)*aux1)+a.x); b1.y=(((u.y)*aux1)+a.y); b1.z=(((u.z)*aux1)+a.z); /* une fois que l'équation du second degré est resolu, on obtient 0,1 ou 2 points d'intersection*/ b2.x=(((u.x)*aux2)+a.x); /*selon le signe du delta */ b2.y=(((u.y)*aux2)+a.y); b2.z=(((u.z)*aux2)+a.z); vecteur3d ab1,ab2; ab1=vecteur3d(a,b1); ab2=vecteur3d(a,b2); // on retourne le point d'intersection le plus proche n1=ab1.norme(); n2=ab2.norme(); if(n1suiv=NULL; /* ( while((pm->suiv)!=NULL){............................pm=pm->suiv;} ) */ premier=aux; /* sans cette méthode on ne peut pas atteindre le dernier maillon */ } //METHODE AJOUTE void listesol :: ajoute(sphere sph) { /* cette méthode ajoute la sphere sph à la liste de spheres */ maillon * a; /* on crée un nouveau mailon*/ a= new maillon; (a->ps)=sph; /* ce maillon contient la sphere parametre et pointe vers le premier maillon */ (a->suiv)=premier; /* de la chaine tandis que le pointeur qui pointe le début de la chaîne pointe */ premier=a; /* le maillon ainsi crée. On a bien insérer le maillon crée en début de chaîne */ }; //METHODE SUIVANT ET FIRST maillon * listesol:: suivant() { return premier->suiv; }; maillon * listesol:: first(){ return premier; }; //METHODE RETOURNERAYON1 /* cette méthode retourne le rayon qui passe par le point ou se situe "l'oeil" */ rayon retournerayon1(int i, int j){ /* et le pixel de l'écran de coordonéées (f,g) */ double step=(2.0/((3*n)-1)); point3d pixel(0,(1-(i*step)),(1-(j*step))); /* on calcul le coordonnée du pixel ds le referentiel */ point3d pdvue(-2,0,0); vecteur3d aux(pdvue,pixel); /* on calcule le vecteur qui part de l'oeil et qui va au pixel en question */ rayon ra; /* on fabrique le rayon d'origine le pixel et de vecteur le vecteur ci dessus normé */ ra=rayon(pixel,aux); return ra; /* on retourne le rayon ainsi crée */ } /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ CLASSE SOURCE @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ // CONSTRUCTEURS DE LA CLASSE SOURCE source :: source(){}; source :: source(point3d a,RGB b){ origine=a; couleur=b; } // METHODES DE LA CLASSE SOURCE //METHODE GETORIGINE point3d source :: getorigine(){ return origine; } //METHODE GETCOULEUR RGB source :: getcouleur(){ return couleur; }; //METHODE RAYONP3DS rayon source:: rayonp3ds(point3d a){ /*cette methode retourne le rayon passant par le point source lumineuse et */ vecteur3d aux; /* le point a*/ aux=vecteur3d(origine,a); rayon aux1; aux1=rayon(origine,aux); return aux1; }; //METHODE TEST int source:: test(point3d a,listesol c){ /* Cette méthode test si le point a est éclairé par la source ou caché */ maillon *pm; /* par un esphere de la liste de sphere c*/ pm=c.first(); point3d inter(-199,0,0); /* on définit un point d'intersection par deafut */ sphere * sol; /* on définit un pointeur sur une sphère */ rayon aux; aux=rayonp3ds(a); /* on determine le rayon passant par le point a et le point source lumineuse*/ while(pm->suiv!=NULL){ /* on parcours la liste de sphere*/ point3d p(-199,0,0); /* on définit un point d'intersection variable par défaut*/ sol=&(pm->ps); p=sol->intersection(aux); /*on calcul le point d'intersection de la sphere du maillon sur lequel on se trouve et du rayon */ if(p.x!=-199 && inter.x!=-199){ /* si l'intersection par défaut et l'intersection variable ont changé depuis le début */ if(distance(origine,p)suiv;; } if(distance(inter,a)>0.01){ /* si la distance entre le point d'intersection et le point paramètre est superieure à 0.01 */ return 1; /* (arrondissement dans le calcul de la norme) alors le point a est caché de la source par */ } /* un autre point . Donc on retourne 1 */ else return 0; /* sinon on retourne 0 */ }; /*############################################################################# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ MAIN @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ##############################################################################*/ void main(void){ /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ CREATION DES SPHERES @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ //On définit tout d'abord les 3 paramètres de chaque spheres avant d'apeler //le constructeur sphere : -Le centre , -Le rayon , -La couleur // creation de la sphere1 point3d centre1(6,1,-1); RGB couleur1(0.3,0.15,0.7); double rayon1=0.5; sphere sphere1(centre1,rayon1,couleur1); cout<<"sphere 1 : "; sphere1.ecrire(); //creation de la sphere2 point3d centre2(9,-2,-1); RGB couleur2(0.11,0.41,0.11); double rayon2=2; sphere sphere2(centre2,rayon2,couleur2); cout<<"sphere 2 : "; sphere2.ecrire(); //creation de la sphere3 point3d centre3(20,4,3); RGB couleur3(0.2,0.2,0.3); double rayon3=3; sphere sphere3(centre3,rayon3,couleur3); cout<<"sphere 3 : "; sphere3.ecrire(); //création de la sphere4 point3d centre4(14,5,0); RGB couleur4(0.8,0.3,0.1); double rayon4=0.6; sphere sphere4(centre4,rayon4,couleur4); cout<<"sphere 4 : "; sphere4.ecrire(); /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ CREATION DE LA LISTE DE SPHERE @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ //On utilise la methode ajoute(sphere) pour placer les spheres désirées dans la liste. //REMARQUE (rappel) la première methode à apeler après le constructeur est la méthode ajoute0() //qui a été créer afin de permettre de balayer toute la liste de sphere par la suite //creation de la liste de solide liste1 listesol liste1; liste1.ajoute0(); liste1.ajoute(sphere3); liste1.ajoute(sphere2); liste1.ajoute(sphere1); liste1.ajoute(sphere4); /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ CREATION DE LA SOURCE LUMINEUSE @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ //creation de la source de lumiere source1 point3d sp3d(0,8,-3); RGB sRGB(0.8,0.8,0.8); source source1(sp3d,sRGB); /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ CALCUL DE L'IMAGE @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ //CREATION DE L'IMAGE Image scene2(3*n,4*n); int f,g; RGB couleur11(0.2,0.2,0.2); Couleur Cr = couleur1.convertir(); point3d a(-2,0,0); rayon raytest; sphere solid; point3d p; point3d inter; sphere s; maillon *pm; pm=new maillon; //CALCUL DE L'IMAGE (on calcul ici une image en format 4/3 =>plus pratique pour fond d'écran, photos,etc....) for(f=1;f<(3*n);f++){ /* f correspond au numéro de la ligne de l'image ou l'on se situe , la limite superieure étant 3*n*/ for(g=1;g<(4*n);g++){ /*g correspond au numéro de la colonne de l'image où l'on se situe , la limite supériere étant 4*n*/ //METHODE POURCENTAGE double pourcentage=((f*100)/(3*n));double pourcentage1;if(f==1){pourcentage1=pourcentage;} if(pourcentage<100){ /* Cette méthode a pour but de donner un indice de l'état d'avancement du calcul en % */ if(floor (pourcentage)==pourcentage1+1){ cout<suiv!=NULL){ /*on parcours la liste de sphere de maillon en maillon jusqu'a arriver sur le maillon 0 */ solid=pm->ps; /* on se place sur la sphere du maillon sur lequel on est */ raytest=retournerayon1(f,g); /* on creer le rayon qui passe par le pixel de la ligne f et de la collonne g*/ p=solid.intersection(raytest); /* on enregistre l'intersection de ce rayon avec la sphere */ if(p.x!=-199 && inter.x!=-199){ /* si le rayon intercepte la sphere (au point p) et en a deja intercepter une (au point inter) */ if(distance(a,p)suiv; /* on recommence avec la sphere du maillon suivant */ } if(inter.x==-199){ /* si l'intersection par defaut est l'intersection initiale, le rayon n'a pas rencontrer de sphere */ Couleur Cf;double ee;ee=(f/(4)); couleur11=RGB(ee,ee,ee); /* on convertit la couleur du fond de RGB en Couleur . Ici la couleur depends de la ligne sur */ Cf=couleur11.convertir(); /*laquelle on se situe (f) afin de creer un degradé de la couleur de fond */ scene2.setCouleur(f,g,Cf); /* le pixel decoordonnées (f,g) prends donc la couleur de fond */ } else{ /* si l'intersection par defaut n'est pas l'interstion initiale, le rayon a renconté une sphere */ Couleur Cf;RGB Ct,Ca; Ct=s.getcolor(); vecteur3d n;n=s.calculnormale(inter); /* on definit le vecteur normal à la sphere passant par le point d'intersection */ vecteur3d rss;rss=(source1.rayonp3ds(inter)).raydirection(); /*on définit le vecteur directeur du rayon partant de l'origine de la */ if((source1.test(inter,liste1))==0){ /* source lumineuse at allant vers le point d'intersection */ double pr;pr=prodscal(n,rss); /* on calcul le produit scalaire de ces deux vecteurs */ if(pr<0){pr=-pr;}; Ca=mul(pr,source1.getcouleur()); /* l'apport lunineux de la source lumineuse est proportionnel à ce porduit scalaire */ Ct=somme(Ca,Ct); /* la couleur du point considéré est la somme de sa couleur d'origine plus la */ Cf=Ct.convertir(); /* contribution de la source lumineuse */ scene2.setCouleur(f,g,Cf); /*le pixel de coordonnées(f,g) prends donc la couleur ainsi calculée */ } else if((source1.test(inter,liste1))==1){ Cf=Ct.convertir(); scene2.setCouleur(f,g,Cf); } } } } /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ SAUVEGARDE DE L'IMAGE @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ cout<<"100%" <