Pastebin
Retrouvez, créez et partagez vos snippets en temps réel.
Rechercher un Pastebin
Aucun paste trouvé.
Créer un paste
Pastebin
Blog
qfsd
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> struct Pixel { double R; //valeur de rouge double G; //valeur de vert double B; // valeur de bleu }; typedef struct Pixel PIXEL; struct Surface { int width; //largeur int height; //hauteur // int depth; //nb de bits par pixel PIXEL *data; //pixels }; typedef struct Surface SURFACE; //constructeur int Surface_Init(SURFACE *s, int width, int height) { if (width < 1 || height < 1 ) return 0; PIXEL *tableau = malloc( width * height * sizeof s->data[0]); if (tableau == NULL) return 0; s->data = tableau; s->width = width; s->height = height; // memset(tableau, 0, width * height * sizeof s->data[0]) for (int i = 0 ; i < s->width * s->height; ++i) { (s->data + i)->R = 0.0; (s->data + i)->G = 0.0; (s->data + i)->B = 0.0; } // s->depth = 255; // ??? return 1; } //destructeur void Surface_Kill(SURFACE *s) { free(s->data); } //remplissage void fill(SURFACE *s, PIXEL valeur) { for (int i = 0 ; i < s->width * s->height ; ++i){ s->data[i] = valeur; } } PIXEL *at(SURFACE *s,int x,int y) { if (x<0 || x>= s-> width) return NULL; if (y<0 || y>= s-> height) return NULL; return s->data + y *s->width +x; } //sauver sur disque int pgm_write(SURFACE *s, FILE *f, int max) { fprintf(f, "P3\n# png_write\n%d %d \n%d\n",s->width,s->height,max); int nbpix = s-> width*s->height; int e,i; for(i=0,e=nbpix;i!=e;++i) { int valueR = s->data[i].R * max; fprintf(f,"%d\n",valueR); int valueG = (s->data + i)->G*max; fprintf(f,"%d\n",valueG); int valueB = (s->data + i)->B*max; fprintf(f,"%d\n",valueB); } return 1; } void rectangle_plein(SURFACE *s, int xmin,int ymin,int width, int height,PIXEL couleur) { for (int y=ymin;y<ymin+height;++y) { for(int x=xmin;x<xmin + width; ++x) { PIXEL * pixel = at(s,x,y); if (pixel!=NULL){ *pixel = couleur; } } } } void rectangle_degrade(SURFACE *s, int xmin, int ymin, int width, int height, PIXEL c1, PIXEL c2) { for (int y = ymin; y < ymin + height; ++y) { // progression verticale : t = 0 en haut, 1 en bas double t = (double)(y - ymin) / height; PIXEL col; col.R = c1.R * (1 - t) + c2.R * t; col.G = c1.G * (1 - t) + c2.G * t; col.B = c1.B * (1 - t) + c2.B * t; for (int x = xmin; x < xmin + width; ++x) { PIXEL *p = at(s, x, y); if (p) *p = col; } } } void line(SURFACE *s, int x0, int y0, int x1, int y1, PIXEL color) { int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1; int err = dx + dy; while (1) { PIXEL *p = at(s, x0, y0); if (p) *p = color; if (x0 == x1 && y0 == y1) break; int e2 = 2 * err; if (e2 >= dy) { err += dy; x0 += sx; } if (e2 <= dx) { err += dx; y0 += sy; } } } void triangle_plein(SURFACE *s, int x1,int y1, int x2,int y2, int x3,int y3, PIXEL col) { // tri des points par y if (y2 < y1) {int t=x1;x1=x2;x2=t; t=y1;y1=y2;y2=t;} if (y3 < y1) {int t=x1;x1=x3;x3=t; t=y1;y1=y3;y3=t;} if (y3 < y2) {int t=x2;x2=x3;x3=t; t=y2;y2=y3;y3=t;} int total_height = y3 - y1; for (int i = 0; i < total_height; i++) { int second_half = i > y2 - y1 || y2 == y1; int segment_height = second_half ? y3 - y2 : y2 - y1; float alpha = (float)i / total_height; float beta = (float)(i - (second_half ? y2 - y1 : 0)) / segment_height; int Ax = x1 + (x3 - x1) * alpha; int Bx = second_half ? x2 + (x3 - x2) * beta : x1 + (x2 - x1) * beta; if (Ax > Bx) { int t=Ax; Ax=Bx; Bx=t;} for (int x = Ax; x <= Bx; x++) { PIXEL *p = at(s, x, y1 + i); if (p) *p = col; } } } void maison(SURFACE *s, int x, int y, int k) //a partir de en haut a gauche de la maison { //def couleur PIXEL gris = {.R=0.589,.G=0.593,.B=0.593}; PIXEL noir = {.R=0.138,.G=0.151,.B=0.141}; PIXEL beige = {.R=0.847,.G=0.82,.B=0.675}; //def positions int murW = 100 * k; int murH = 40 * k; int toitH = 20 * k; // hauteur du toit int fen1x = 5 * k; // fenêtres int fen1y = 10 * k; int fen1w = 20 * k; int fen1h = 10 * k; int fen2x = 50 * k; int fen2y = 10 * k; int fen2w = 30 * k; int fen2h = 17 * k; ////// rectangle_plein(s, x, y, murW, murH, beige); triangle_plein(s,x,y,x + murW/2,y - toitH,x + murW,y,gris); rectangle_plein(s,x + fen1x, y + fen1y,fen1w, fen1h,noir); rectangle_plein(s,x + fen2x, y + fen2y,fen2w, fen2h,noir); } void cercle_plein(SURFACE *s, int cx, int cy, int r, PIXEL col) { for (int y = -r; y <= r; y++) { for (int x = -r; x <= r; x++) { if (x*x + y*y <= r*r) { // Test d’appartenance au disque PIXEL *p = at(s, cx + x, cy + y); if (p) *p = col; } } } } void quart_de_cercle_plein(SURFACE *s, int cx, int cy,int r,double angle_deg,PIXEL col) { double start = angle_deg * M_PI / 180.0; double end = (angle_deg + 90.0) * M_PI / 180.0; for (int y = -r; y <= r; ++y) { for (int x = -r; x <= r; ++x) { // point réel dans l'image int px = cx + x; int py = cy + y; if (x*x + y*y > r*r) continue; // extérieur du cercle // Calcul de l'angle du point double theta = atan2(-y, x); // -y car Y de l’image inversé if (theta < 0) theta += 2 * M_PI; // convertir en [0, 2pi] if (theta >= start && theta <= end) { PIXEL *p = at(s, px, py); if (p) *p = col; } } } } void ellipse_plein(SURFACE *s, int cx, int cy, int rx, int ry, PIXEL col) { double rx2 = rx * rx; double ry2 = ry * ry; for (int y = -ry; y <= ry; y++) { for (int x = -rx; x <= rx; x++) { // équation de l’ellipse double e = (x*x) / rx2 + (y*y) / ry2; if (e <= 1.0) { // point dans l'ellipse PIXEL *p = at(s, cx + x, cy + y); if (p) *p = col; } } } } void enjoliveur(SURFACE *s, int cx, int cy, int rayon, int nbBranches, PIXEL color) { if (nbBranches < 1 || rayon < 1) return; // longueur réelle des branches (légèrement intérieure au cercle) float branchLen = rayon - 1; // tu peux ajuster (rayon * 0.9f par exemple) for (int i = 0; i < nbBranches; i++) { float angle = (2.0f * M_PI / nbBranches) * i; int x2 = cx + (int)(cosf(angle) * branchLen); int y2 = cy + (int)(sinf(angle) * branchLen); line(s, cx, cy, x2, y2, color); } } PIXEL* loadPPM_as_PIXELS(const char *filename, int *w, int *h) { FILE *f = fopen(filename, "rb"); if (!f) return NULL; char magic[3]; if (fscanf(f, "%2s", magic) != 1) { fclose(f); return NULL; } if (strcmp(magic, "P3") != 0 && strcmp(magic, "P6") != 0) { fclose(f); return NULL; } // Fonction utilitaire pour ignorer les commentaires int c; do { c = fgetc(f); if (c == '#') { // ignorer toute la ligne while ((c = fgetc(f)) != '\n' && c != EOF); } } while (c == '\n' || c == '\r' || c == ' ' || c == '\t'); ungetc(c, f); // lecture largeur, hauteur, max int max; if (fscanf(f, "%d %d %d", w, h, &max) != 3) { fclose(f); return NULL; } if (*w <= 0 || *h <= 0 || max <= 0) { fclose(f); return NULL; } // sauter un caractère de fin de ligne fgetc(f); PIXEL *pix = malloc((*w) * (*h) * sizeof(PIXEL)); if (!pix) { fclose(f); return NULL; } if (strcmp(magic, "P6") == 0) { for (int i = 0; i < (*w) * (*h); i++) { unsigned char rgb[3]; if (fread(rgb, 1, 3, f) != 3) { free(pix); fclose(f); return NULL; } pix[i].R = rgb[0] / (double)max; pix[i].G = rgb[1] / (double)max; pix[i].B = rgb[2] / (double)max; } } else { for (int i = 0; i < (*w) * (*h); i++) { int r, g, b; if (fscanf(f, "%d %d %d", &r, &g, &b) != 3) { free(pix); fclose(f); return NULL; } pix[i].R = r / (double)max; pix[i].G = g / (double)max; pix[i].B = b / (double)max; } } fclose(f); return pix; } void draw_ppm_scaled(SURFACE *s, PIXEL *ppm_data, int ppm_w, int ppm_h, int dst_x, int dst_y, int dst_w, int dst_h) { for (int y = 0; y < dst_h; y++) { for (int x = 0; x < dst_w; x++) { // coordonnée source (échelle bilinéaire simple → nearest neighbor) int src_x = (x * ppm_w) / dst_w; int src_y = (y * ppm_h) / dst_h; PIXEL src = ppm_data[src_y * ppm_w + src_x]; PIXEL *p = at(s, dst_x + x, dst_y + y); if (p != NULL) *p = src; } } } int main() { int dim; printf("Dimension du cadre ? (ex: 500) : "); scanf("%d", &dim); double k = dim / 500.0; // facteur d'échelle // définition des couleurs PIXEL blanc0 = {.R=1,.G=1,.B=1}; PIXEL blanc = {.R=0.85,.G=0.85,.B=0.85}; PIXEL bleu1 = {.R=0.11,.G=0.278,.B=0.408}; PIXEL bleu2 = {.R=0.494,.G=0.718,.B=0.804}; PIXEL vert = {.R=0.31,.G=0.42,.B=0.239}; PIXEL gris = {.R=0.589,.G=0.593,.B=0.593}; PIXEL marron = {.R=0.133,.G=0.015,.B=0.07}; PIXEL noir = {.R=0,.G=0,.B=0}; PIXEL bleuvitre = {.R=0.235,.G=0.349,.B=0.349}; PIXEL jaune = {.R=0.682,.G=0.714,.B=0.035}; PIXEL rouge = {.R=0.671,.G=0.016,.B=0.020}; PIXEL grisombre = {.R=0.135,.G=0.135,.B=0.135}; PIXEL vertfonce = {.R=0.128,.G=0.233,.B=0.062}; PIXEL grismoyensombre = {.R=0.314,.G=0.314,.B=0.314}; SURFACE dessin = {0,0,NULL}; if (Surface_Init(&dessin, dim, dim) == 0) { printf("Erreur init surface!\n"); return 1; } fill(&dessin, blanc); // --- FOND --- rectangle_degrade(&dessin, 25*k, 25*k, 450*k, 200*k, bleu1, bleu2); rectangle_plein(&dessin, 25*k,225*k,450*k,50*k,vert); rectangle_plein(&dessin, 25*k,275*k,450*k,150*k,gris); rectangle_degrade(&dessin, 25*k,275*k,450*k,150*k, gris, grismoyensombre); // chemins triangle_plein(&dessin, 387*k,230*k, 418*k,276*k, 443*k,230*k, gris); triangle_plein(&dessin, 474*k,276*k, 418*k,276*k, 443*k,230*k, gris); triangle_plein(&dessin, 37*k,230*k, 6*k,276*k, 93*k,230*k, gris); triangle_plein(&dessin, 62*k,276*k, 6*k,276*k, 93*k,230*k, gris); rectangle_plein(&dessin, 75*k,246*k,400*k,10*k,gris); rectangle_plein(&dessin, 0*k,240*k,25*k,100*k,blanc); // arbres ellipse_plein(&dessin, 110*k,195*k, 10*k,25*k, vertfonce); ellipse_plein(&dessin, 180*k,185*k, 8*k,27*k, vertfonce); ellipse_plein(&dessin, 290*k,200*k, 4*k,25*k, vertfonce); ellipse_plein(&dessin, 450*k,180*k, 10*k,25*k, vertfonce); // maisons maison(&dessin, 27*k, 192*k, k); maison(&dessin, 149*k,193*k, k); maison(&dessin, 373*k,191*k, k); // buissons rectangle_plein(&dessin, 445*k,220*k,27*k,15*k,vertfonce); rectangle_plein(&dessin, 85*k,220*k,50*k,18*k,vertfonce); // ombre voiture ellipse_plein(&dessin, 275*k,290*k, 135*k,20*k, grisombre); // --- VOITURE --- rectangle_plein(&dessin, 140*k,255*k,175*k,40*k,marron); quart_de_cercle_plein(&dessin, 140*k,255*k,40*k,180,marron); triangle_plein(&dessin, 100*k,255*k, 200*k,255*k, 200*k,185*k, marron); rectangle_plein(&dessin, 200*k,185*k,155*k,70*k,marron); quart_de_cercle_plein(&dessin, 350*k,219*k,35*k,0,marron); rectangle_plein(&dessin, 310*k,215*k,75*k,70*k,marron); cercle_plein(&dessin, 333*k,285*k,20*k,noir); cercle_plein(&dessin, 333*k,285*k,15*k,gris); cercle_plein(&dessin, 145*k,285*k,20*k,noir); cercle_plein(&dessin, 145*k,285*k,15*k,gris); // détails rectangle_plein(&dessin, 107*k,264*k,21*k,6*k, blanc); rectangle_plein(&dessin, 164*k,264*k,148*k,6*k, blanc); rectangle_plein(&dessin, 351*k,264*k,30*k,6*k, blanc); rectangle_plein(&dessin, 221*k,264*k,3*k,6*k, marron); rectangle_plein(&dessin, 284*k,264*k,3*k,6*k, marron); // vitres rectangle_plein(&dessin, 200*k,193*k,10*k,40*k, bleuvitre); triangle_plein(&dessin, 148*k,233*k, 200*k,193*k, 200*k,233*k, bleuvitre); rectangle_plein(&dessin, 220*k,193*k,70*k,40*k, noir); rectangle_plein(&dessin, 300*k,193*k,60*k,40*k, noir); // phares ellipse_plein(&dessin, 108*k,253*k, 6*k,5*k, jaune); rectangle_plein(&dessin, 374*k,235*k,11*k,23*k, rouge); // poignées ellipse_plein(&dessin, 203*k,246*k, 6*k,3*k, noir); ellipse_plein(&dessin, 228*k,246*k, 6*k,3*k, noir); // enjoliveurs enjoliveur(&dessin, 333*k,285*k,15*k,25, blanc); enjoliveur(&dessin, 145*k,285*k,15*k,25, blanc); // images importées int ppm_w, ppm_h; PIXEL *ppm_pixels = loadPPM_as_PIXELS("PARENTAL.ppm", &ppm_w, &ppm_h); if (ppm_pixels) { draw_ppm_scaled(&dessin, ppm_pixels, ppm_w, ppm_h, 380*k, 430*k, 95*k, 65*k); free(ppm_pixels); } ppm_pixels = loadPPM_as_PIXELS("GKMC.ppm", &ppm_w, &ppm_h); if (ppm_pixels) { draw_ppm_scaled(&dessin, ppm_pixels, ppm_w, ppm_h, 165*k, 430*k, 200*k, 66*k); free(ppm_pixels); } FILE *fichier = fopen("goodkid.ppm", "w"); if (fichier) { pgm_write(&dessin, fichier, 255); fclose(fichier); } Surface_Kill(&dessin); printf("jai fini\n"); getchar(); return 0; }
Créé il y a 1 mois.