#define _C_td4 /* * ---------------------------------------------------------------------------- * * Fichier : td4.c * Langage : C ANSI * Auteur : P. Dechamboux * Creation : 7 novembre 1995 * ---------------------------------------------------------------------------- * Description : * Programme de manipulation de rectangles dont les cotes sont paralleles * aux axes du repere ortho-norme dans lequel ils sont definis. * ---------------------------------------------------------------------------- * Interventions * >>>>>>>>>>>>> * ---------------------------------------------------------------------------- * Fonctions definies * Locales : * AfficheErreur, * LireCoord, * LireRect, * Surface, * TranslateRect, * RectEnglob. * Exportees : main. * * ---------------------------------------------------------------------------- */ /****************************************************************************/ /*------------------- INCLUSION DES INTERFACES SYSTEMES --------------------*/ /****************************************************************************/ #include #include /****************************************************************************/ /*----------------- INCLUSION DES INTERFACES APPLICATIVES ------------------*/ /****************************************************************************/ /****************************************************************************/ /*------------------- CONSTANTES, MACROS & TYPES LOCAUX --------------------*/ /****************************************************************************/ /* Definition de la taille maximum du nom d'un rectangle */ #define TAILLEMAX 20 /* Definition du cadre d'inclusion des rectangles */ #define MIN_X -100 #define MAX_X 100 #define MIN_Y -50 #define MAX_Y 50 /* Definition d'un point dans le repere ortho-norme */ typedef struct { float x; /* abscisse du point */ float y; /* ordonnee du point */ } Point; /* Definition d'un rectangle dont les cotes sont paralleles aux axes du repere * ortho-norme */ typedef struct { char nom[TAILLEMAX]; Point bas_gauche; Point haut_droit; } Rectangle; /****************************************************************************/ /*------------------- SIGNATURES DES FONCTIONS LOCALES ---------------------*/ /****************************************************************************/ static void AfficheErreur(int errnum); static float LireCoord (int binf, int bsup); static Rectangle LireRect (void); static float Surface (Rectangle rect); static void TranslateRect(Rectangle *rect); static void RectEnglob (const Rectangle *r1, const Rectangle *r2, Rectangle *r); /****************************************************************************/ /*------------------- DEFINITIONS DES VARIABLES LOCALES --------------------*/ /****************************************************************************/ /****************************************************************************/ /*------------------- IMPLANTATION DES FONCTIONS LOCALES -------------------*/ /****************************************************************************/ /* * ---------------------------------------------------------------------------- * * Fonction : AfficheErreur * Resultat : void * Parametres : * Nom Type Role * errnum int Code d'erreur. * Description : * Affiche le commentaire correspondant au code d'erreur passe en * parametre. * * ---------------------------------------------------------------------------- */ static void AfficheErreur( int errnum) { switch (errnum) { case 0 : printf("*** ERREUR : erreur indefinie ***\n"); break; case 1 : printf("*** ERREUR : reel non positif ou nul ***\n"); break; case 2 : printf("*** ERREUR : reel hors de l'intervalle ***\n"); break; default : printf("Code d'erreur inconnu.\n"); } } /* * ---------------------------------------------------------------------------- * * Fonction : LireCoord * Resultat : float Coordonnee lue. * Parametres : * Nom Type Role * binf int Borne inferieure de l'intervalle. * bsup int Borne superieure de l'intervalle. * * Description : * Lit une coordonnee appartenant a l'intervalle specifie par les deux * bornes passes en parametre. * * ---------------------------------------------------------------------------- */ static float LireCoord( int binf, int bsup) { float coord; int valeur_correct = 0; while (!valeur_correct) { printf("\t\tValeur de la coordonnee ? "); fflush(stdin); if (scanf("%f", &coord) != 1) AfficheErreur(0); else if ((coord < (float)binf) || (coord > (float)bsup)) AfficheErreur(2); else valeur_correct = 1; } return coord; } /* * ---------------------------------------------------------------------------- * * Fonction : LireRect * Resultat : Rectangle Le rectangle lu. * Parametres : * Nom Type Role * * Description : * Lit un rectangle et le retourne en resultat de la fonction. * * ---------------------------------------------------------------------------- */ static Rectangle LireRect( void) { Rectangle rect_lu; printf("\tNom du rectangle ? "); scanf(%20s", rect_lu.nom); do { printf("\tLecture de l'abscisse du coin bas gauche\n"); rect_lu.bas_gauche.x = LireCoord(MIN_X, MAX_X); printf("\tLecture de l'ordonnee du coin bas gauche\n"); rect_lu.bas_gauche.y = LireCoord(MIN_Y, MAX_Y); printf("\tLecture de l'abscisse du coin haut droit\n"); rect_lu.haut_droit.x = LireCoord(MIN_X, MAX_X); printf("\tLecture de l'ordonnee du coin haut droit\n"); rect_lu.haut_droit.y = LireCoord(MIN_Y, MAX_Y); } while ((rect_lu.bas_gauche.x > rect_lu.haut_droit.x) || (rect_lu.bas_gauche.y > rect_lu.haut_droit.y)); return rect_lu; } /* * ---------------------------------------------------------------------------- * * Fonction : Surface * Resultat : float Surface couverte par rectangle. * Parametres : * Nom Type Role * rect Rectangle Rectangle dont on veut la surface. * * Description : * Calcule la surface du rectangle passe en parametre. * * ---------------------------------------------------------------------------- */ static float Surface( Rectangle rect) { return (rect.haut_droit.x - rect.bas_gauche.x) * (rect.haut_droit.y - rect.bas_gauche.y); } /* * ---------------------------------------------------------------------------- * * Fonction : TranslateRect * Resultat : void * Parametres : * Nom Type Role * rect Rectangle * Rectangle a translater. * * Description : * Translate un rectangle de 20 en abscisse et en ordonnee. S'il sort du * cadre d'inclusion en partie, il est coupe a la frontiere. S'il sort * totalement, il se limite alors a un point (le coin haut droit). * * ---------------------------------------------------------------------------- */ static void TranslateRect( Rectangle *rect) { rect->haut_droit.x += 20; rect->haut_droit.y += 20; rect->bas_gauche.x += 20; rect->bas_gauche.y += 20; if (rect->haut_droit.x > MAX_X) rect->haut_droit.x = MAX_X; if (rect->haut_droit.y > MAX_Y) rect->haut_droit.y = MAX_Y; if (rect->bas_gauche.x > MAX_X) rect->bas_gauche.x = MAX_X; if (rect->bas_gauche.y > MAX_Y) rect->bas_gauche.y = MAX_Y; } /* * ---------------------------------------------------------------------------- * * Fonction : RectEnglob * Resultat : void * Parametres : * Nom Type Role * r1 Rectangle * Premier rectangle (passe par variable pour * cause d'economie memoire donc non modifie). * r2 Rectangle * Deuxieme rectangle (passe par variable pour * cause d'economie memoire donc non modifie). * r Rectangle * Rectangle resultant. * * Description : * Calcule le rectangle englobant les deux rectangles "r1" et "r2" passes * en parametre. Le resultat est stocke dans le rectangle "r". * * ---------------------------------------------------------------------------- */ static void RectEnglob( Rectangle *r1, Rectangle *r2, Rectangle *r) { strcpy(r->nom, r1->nom); strncat(r->nom, r2->nom, TAILLEMAX - strlen((r->nom)); r->haut_droit.x = ((r1->haut_droit.x > r2->haut_droit.x) ? r1->haut_droit.x : r2->haut_droit.x); r->haut_droit.y = ((r1->haut_droit.y > r2->haut_droit.y) ? r1->haut_droit.y : r2->haut_droit.y); r->bas_gauche.x = ((r1->bas_gauche.x < r2->bas_gauche.x) ? r1->bas_gauche.x : r2->bas_gauche.x); r->bas_gauche.y = ((r1->bas_gauche.y < r2->bas_gauche.y) ? r1->bas_gauche.y : r2->bas_gauche.y); } /****************************************************************************/ /*------------------ IMPLANTATION DES FONCTIONS EXPORTEES ------------------*/ /****************************************************************************/ /* * ---------------------------------------------------------------------------- * * Fonction : main * Resultat : long Code d'erreur commande. * Parametres : * Nom Type Role * * Description : * Point d'entree du programme "td4" obtenu par compilation du fichier * "td4.c" (cc -o td4 td4.c). * * ---------------------------------------------------------------------------- */ long main() { Rectangle rect, rect1, rect2; printf("Lecture d'un rectangle :\n"); rect = LireRect(); printf("\nSurface de ce rectangle : %f.\n", Surface(rect)); printf("\nTranslation du rectangle :\n"); TranslateRect(&rect); printf("Le rectangle <%s> est maintenant\n\tcoin bas gauche = (%f,%f)\n\tcoin haut droit = (%f,%f)\n", rect.nom, rect.bas_gauche.x, rect.bas_gauche.y, rect.haut_droit.x, rect.haut_droit.y); printf("\nCalcul du rectangle englobant deux autres rectangles:\n"); printf("Lecture d'un premier rectangle :\n"); rect1 = LireRect(); printf("Lecture d'un deuxieme rectangle :\n"); rect2 = LireRect(); RectEnglob(&rect1, &rect2, &rect); printf("Le rectangle <%s> englobant est\n\tcoin bas gauche = (%f,%f)\n\tcoin haut droit = (%f,%f)\n", rect.nom, rect.bas_gauche.x, rect.bas_gauche.y, rect.haut_droit.x, rect.haut_droit.y); printf("\n\nFin du programme.\n"); return(0); }