IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

procédure remplissage d'un calque


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    étudiant
    Inscrit en
    Décembre 2022
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : étudiant

    Informations forums :
    Inscription : Décembre 2022
    Messages : 7
    Points : 3
    Points
    3
    Par défaut procédure remplissage d'un calque
    Bonjour ! Je suis en train de travailler sur un interpréteur pour un petit langage graphique et je suis actuellement en train de coder une procédure qui va me permette d'imiter l'outil "remplissage" des logiciels de dessin. Ma procédure doit remplir la zone de même couleur autour du curseur en la remplaçant par la couleur courante. Voici le code que j'ai écrit, j'ai essayé de procéder en utilisant une pile explicite de pixel dans laquelle j'ai mis l'ensemble des positions qui reste à traiter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    void fill_using_stack(int x0,int y0, calque *calque,pixel nouveau,int taille_calque){
     
        // j'intialise ma pile de pixel
     
        stack_pixel r; 
        pixel px_comparaison;
        r=create_empty_stack_pixel();
        // j'ajoute le pixel de mon calque à la position (x0,y0) dans la pile
     
        if(comparaison_pixel(calque->tab[y0][x0],nouveau)==0){
            return;
        }
        push_pixel(calque->tab[y0][x0],&r);
     
        // on initialise une variable qui va permettre de nous déplacer dans le calque
     
        // j'initialise les cordonnées (x,y) du 1er pixel
        int x,y;
        x=x0;
        y=y0;
        //boucle while sur la pile: condition d'arrêt lorsque la pile est vide
     
        while(!is_empty_stack_pixel(r)){
            // j'enlève un pixel de la pile 
            px_comparaison=pop_pixel(&r);
     
            // je remplace le pixel sorti de la pile par le nouveau pixel
            set_pixel(&px_comparaison,nouveau);
            // puis je le mets dans le calque à sa position 
            set_calque_pixel(x,y,calque,px_comparaison);
            // condition sur la coordonée y pour éviter un dépassement du calque ( tableau à 2D )
            if(y>0){
                // je compare le pixel au nord avec le pixel de remplacement ( nouveau )
                if(comparaison_pixel(calque->tab[y-1][x],nouveau)==0){ // si c'est = 0 ça veut dire que les 2 pixels sont différents,
                push_pixel(calque->tab[y-1][x],&r); // dans ce cas mets le pixel au nord dans la pile 
                }
                // je décrémente ma coordonée y pour me déplacer au nord
                y=y-1;
            }
     
            /*même idée pour les autres coordonées : pixel nord,est,ouest */
            if(y<taille_calque-1){
                if(comparaison_pixel(calque->tab[y+1][x],nouveau)==0){
                push_pixel(calque->tab[y+1][x],&r);
                }
                y=y+1;
            }
            if(x<taille_calque-1){
                if(comparaison_pixel(calque->tab[y][x+1],nouveau)==0){
                push_pixel(calque->tab[y][x+1],&r);
                }
                x=x+1;
            }
            if(x>0){
                if(comparaison_pixel(calque->tab[y][x-1],nouveau)==0){
                push_pixel(calque->tab[y][x-1],&r);
                }
                x=x-1;
            }
     
     
        }
     
    }
    avec ça, mon code compile mais cela ne me renvoie rien, mon calque n'est pas dutout modiié

    voici les procédures intermédiaires que j'ai utilisé dans ma procédure de remplissage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    /* fonction pour comparer 2 pixels 
    renvoie 1 si = et 0 sinon */
    int comparaison_pixel(pixel px1,pixel px2){
        if(px1.c.r == px2.c.r && px1.c.v==px2.c.v && px1.c.b==px2.c.b && px1.o.c==px2.o.c){
            return 1;
        }
        else return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    /*procédure qui remplacer le pixel de mon calque à la position (x,y) par un nouveau pixel */
    void set_calque_pixel(int x, int y, calque *ca,pixel px){
        ca->tab[y][x].c.r=px.c.r;
        ca->tab[y][x].c.v=px.c.v;
        ca->tab[y][x].c.b=px.c.b;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /*procédure qui remplacer px1 par px2  */
    void set_pixel(pixel *px1,pixel px2){
        px1->c.r=px2.c.r; // notation : la composante rouge du px1 = la composante rouge du px2
        px1->c.v=px2.c.v;
        px1->c.b=px2.c.b;
    }
    voilà voilà, mon raisonnement concernant l'utilisation de la pile explicite de pixel est sûrement erroné, j'ai essayé de m'inspirer de l'algo de remplissage par diffusion avec pile explicite mais j'ai du mal à utiliser ma variable px_comparaison !
    Je vous remercie par avance, joyeux Nôel !

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 735
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 735
    Points : 31 060
    Points
    31 060
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par alexgpx Voir le message
    voilà voilà, mon raisonnement concernant l'utilisation de la pile explicite de pixel est sûrement erroné, j'ai essayé de m'inspirer de l'algo de remplissage par diffusion avec pile explicite mais j'ai du mal à utiliser ma variable px_comparaison !
    Je pense que tu parles de l'algo de remplissage par diffusion.
    La base de la vérification c'est quand-même de faire ses propres contrôles. Afficher le pixel avant, après, l'état de la pile, etc. Surtout que c'est la pile qui fait tout et que tu n'as rien montré de ses codes.

    Déjà les points qui me posent souci ce sont ces deux instructions : stack_pixel r; r=create_empty_stack_pixel(). Ca me donne ici la grosse impression que "stack_pixel" est un type cachant un pointeur, ce qui est déjà totalement rédhibitoire. Les programmeurs qui sont tellement mal à l'aise avec les étoiles qu'ils vont vite vite les cacher dans des types n'ont rien à faire en C dans lequel la gestion de l'étoile est une condition indispensable pour ce langage. Surtout quand ensuite je vois px_comparaison=pop_pixel(&r) ce qui veut dire que la fonction pop_pixel est déclarée pixel pop_pixel(stack_pixel* pt) et que la tentative de masquer l'étoile non seulement tombe à plat (elle étant réapparue quand-même) mais en plus va déstabiliser tous les lecteurs voyant là un pointeur simple (1 étoile=1D) alors qu'il s'agit en réalité d'un pointeur double (1 étoile visible + 1 étoile masquée = 2 étoiles = 2D).
    Or en C connaitre en permanence ses pointeurs est une obligation si on ne veut pas que son programme parte en UB.

    De plus puisqu'il semble que le souci vient de la pile, avoir les fonctions qui la manipulent aurait été un plus pour essayer de déméler cette pelote.

    De même, si le type "pixel" est un type un peu complexe (une structure?), il est malvenu d'utiliser "=" pour le remplir (px_comparaison=pop_pixel(&r)) car il existe des cas où cette façon de faire soit contre-indiquée. Et quoi qu'il en soit, dans les fonctions, on ne fait pas de transfert de structures (transferts se faisant via les paramètres pour l'input ou via le return pour l'output) pouvant contenir potentiellement plusieurs centaines d'octets (les IO des fonctions étant faits par recopie). Les structures on les passe aux fonctions par leur adresse.

  3. #3
    Candidat au Club
    Homme Profil pro
    étudiant
    Inscrit en
    Décembre 2022
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : étudiant

    Informations forums :
    Inscription : Décembre 2022
    Messages : 7
    Points : 3
    Points
    3
    Par défaut
    Oui,j'ai essayé de m'inspirer de cet algorithme et par ailleurs j'ai complétement oublié de procéder à mes vérifications, chose que je vais corriger !

    Etant encore un débutant en C, les pointeurs ne sont pas encore maitrisé !

    voici les codes de ma pile de pixel ( qui sont les codes usuels pour la manipulation de pile ):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    /* creation d'une structure de pile qui va contenir les differentes pixels*/
    struct stack_pixel{
        pixel p[10]; // à changer 
        int top;
    };
    typedef struct stack_pixel stack_pixel;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* initialisation d'une pile */
    stack_pixel create_empty_stack_pixel(){
        stack_pixel r;
        r.top=-1;
        return r;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /* Vérifier si la pile est vide ou non*/
    int is_empty_stack_pixel(stack_pixel r){
        return r.top<0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    /* Ajouter un pixel dans la pile*/
    void push_pixel(pixel px,stack_pixel *ps){
        if(ps->top<10-1){
            ps->top=ps->top+1;
            ps->p[ps->top]=px;
        }
        else
            printf("Warning : the stack is full");
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* Retirer un pixel et nous le retourner  */
     
    pixel pop_pixel(stack_pixel *ps){
        ps->top=ps->top-1;
        return ps->p[ps->top+1];
    }
    voici également ma structure de pixel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* structue pour un pixel */
    struct pixel{
        couleur c;
        opacite o;
     
    };
    avec couleur et opacité qui sont également des structures :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    /* structure de couleur */
     
    struct couleur{
        composante r;
        composante v;
        composante b;
    };
    typedef struct couleur couleur;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    /* structure pour l'opacite*/
    struct opacite{
        composante c;
    };
    typedef struct opacite opacite;
    Voilà ! le "projet informatique" dans lequel je travaille a un énoncé clair qui nous guide et donc m'a amené à créer toutes ses structures etc... ( je ne sais pas si cela va vous convenir !! )
    Mais d'abord, je vais reprendre mon code de remplissage et procéder à mes vérifications !

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 735
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 735
    Points : 31 060
    Points
    31 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par alexgpx Voir le message
    Etant encore un débutant en C, les pointeurs ne sont pas encore maitrisé !
    C'est malheureusement un incontournable du C.

    Citation Envoyé par alexgpx Voir le message
    voici les codes de ma pile de pixel ( qui sont les codes usuels pour la manipulation de pile ):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    /* creation d'une structure de pile qui va contenir les differentes pixels*/
    struct stack_pixel{
        pixel p[10]; // à changer 
        int top;
    };
    typedef struct stack_pixel stack_pixel;
    Ok, je commence à mieux voir le truc. Ta pile c'est juste un tableau de 10 éléments. Déjà tu partirais de la convention que "pile vide" c'est "top=0" tu pourrais travailler en unsigned et de là en "size_t" qui est le type dédié à stocker des tailles (un unsigned long). Suffit ensuite de bien gérer le moment où le top doit monter (après remplissage et non plus avant). Ensuite en mettant "10" en macro ça devient immédiatement plus évolutif (tu veux passer ta pile à 100 tu fais juste une modif). Et enfin maitriser les pointeurs t'ouvrira la voie vers une pile virtuellement infinie.

    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
     
    #define SZ_ALLOC			(10)
     
    typedef int t_pixel;
     
    // Création d'une structure de pile qui va contenir les differents pixels
    typedef struct {
    	t_pixel* tab;
    	size_t top;
    	size_t size;
    } t_stack;
     
    // Initialisation d'une pile
    void stack_init(t_stack* stack) {
    	stack->top=0;
    	stack->size=0;
    	stack->tab=NULL;
    }
     
    // Ajouter un pixel
    t_stack* stack_push(t_stack* stack, t_pixel* pixel) {
    	// Vérification pile pleine
    	if (stack->top == stack->size) {
    		// Agrandissement
    		stack->size+=SZ_ALLOC;
     
    		// Nouvelle allocation (ou allocation si tab==NULL ce qui est le cas la première fois)
    		t_pixel* new=realloc(stack->tab, stack->size * sizeof(*new));
     
    		// Allocation échouée
    		if (new == NULL) {
    			// Abandon
    			fprintf(stderr, "Critical : the stack is not reallocated\n");
    			free(stack->tab);
    			return NULL;
    		}
     
    		// Allocation ok, récupération nouvelle pile
    		stack->tab=new;
    	}
     
    	// Ici on sait qu'on a la place pour le pixel
    	memcpy(&stack->tab[stack->top], pixel, sizeof(*pixel));
     
    	// On a un pixel de plus
    	stack->top++;
     
    	// Récupération ok
    	return stack;
    }
     
    // Retirer un pixel et nous le retourner
    t_stack* stack_pop(t_stack* stack, t_pixel* pixel) {
    	// Vérification pile vide
    	if (stack->top == 0) {
    		// Abandon
    		fprintf(stderr, "Critical : the stack is empty\n");
    		return NULL;
    	}
     
    	// On a un pixel de moins
    	stack->top--;
     
    	// On récupère le dernier pixel de la pile
    	memcpy(pixel, &stack->tab[stack->top], sizeof(*pixel));
     
    	// Récupération ok
    	return stack;
    }
     
    // Nettoyer la pile
    void stack_free(t_stack* stack) {
    	free(stack->tab);
    }
     
    void stack_dump(t_stack* stack) {
    	if (stack->tab == NULL) {
    		printf("Pile vide, abort\n");
    		return;
    	}
     
    	printf("tab=%p, top=%lu, size=%lu\n", stack->tab, stack->top, stack->size);
    	size_t i;
    	t_pixel* pt;
    	for (i=0, pt=stack->tab; i < stack->top; i++, pt++)
    		printf("tab[%lu/%lu]=%d\n", i+1, stack->top, *pt);
    }
     
    int main() {
    	t_stack stack;
    	t_pixel pixel;
     
    	// Remplissage
    	stack_init(&stack);
    	while (1) {
    		fputs("Entrez un nombre (0 pour terminer) :", stdout); fflush(stdout);
    		scanf("%d", &pixel);
    		if (pixel == 0) break;
    		if (stack_push(&stack, &pixel) == NULL) {
    			fprintf(stderr, "Insertion %d échouée, on recommence\n", pixel);
    			stack_init(&stack);
    			continue;
    		}
    		printf("Insertion %d ok\n", pixel);
    	}
     
    	// Vérification
    	stack_dump(&stack);
     
    	// Récupération
    	while (1) {
    		if (stack_pop(&stack, &pixel) == NULL) {
    			fputs("Récupération terminée\n", stdout);
    			break;
    		}
    		printf("Pixel=%d\n", pixel);
    	}
     
    	// Netoyage
    	stack_free(&stack);
    }
    Voilà une pile virtuellement infinie. Chaque nouveau pixel entrainera, si besoin, un agrandissement du tableau. Et tu remarqueras aussi une espèce de "pseudo-règle" de nommage où toutes les fonctions de gestion de pile commencent par "stack_"...

    Citation Envoyé par alexgpx Voir le message
    Voilà ! le "projet informatique" dans lequel je travaille a un énoncé clair qui nous guide et donc m'a amené à créer toutes ses structures etc... ( je ne sais pas si cela va vous convenir !! )
    Si, c'est pas mal construit. Juste essayer de nommer ses types "t_xxx" afin de les faire ressortir plus facilement dans le code...

    Citation Envoyé par alexgpx Voir le message
    Mais d'abord, je vais reprendre mon code de remplissage et procéder à mes vérifications !
    Oui parce que je me suis inspiré de ton code pour mon exemple et j'ai eu un doute (dans ton code) sur le moment où top doit monter/descendre par rapport à ton "-1" du départ...

  5. #5
    Candidat au Club
    Homme Profil pro
    étudiant
    Inscrit en
    Décembre 2022
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : étudiant

    Informations forums :
    Inscription : Décembre 2022
    Messages : 7
    Points : 3
    Points
    3
    Par défaut
    Merci beaucoup pour l'exemple ! Je me demandais également comment créer une pile dynamique !

    J'aurai une petite question, concernant la taille de la pile. A priori je ne connais pas la taille de ma pile de pixel mais en sachant que mon calque est un tableau 2D de même hauteur et largeur, est ce que lors de l'initialisation de ma pile, si j'écris, en reprenant mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* creation d'une structure de pile qui va contenir les differentes pixels*/
    struct stack_pixel{
        pixel *taille; // je n'écris pas taille[] car je ne connais pas le nombre exact de pixel que pourrait contenir ma pile
        int top;
    };
    typedef struct stack_pixel stack_pixel;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    /* initialisation d'une pile */
    stack_pixel create_empty_stack_pixel(int taille_calque){ // je mets comme argument la taille du calque
        stack_pixel r;
        r.taille[taille_calque*taille_calque]; // ma pile peut donc contenir taille_calque*taille_calque pixel 
        r.top=-1;
        return r;
    }
    est-ce correcte ? Sachant que pour le remplissage de mon calque il pourrait y avoir au plus taille_calque*taille_calque pixel dans ma pile. Ou bien est-ce qu'il est tout de même préférable d'avoir une pile dynamique ? Je ne sais pas ce qui pourrait se passer à ma pile si j'ai une image de taille 1000x1000 par exemple, ma pile pourra accueillir 1000x1000 pixel ? Ou bien autre chose ...

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 735
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 735
    Points : 31 060
    Points
    31 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par alexgpx Voir le message
    Merci beaucoup pour l'exemple ! Je me demandais également comment créer une pile dynamique !
    Je l'ai un peu rectifié et rajouté un main() d'exemple montrant la façon de l'utiliser et ce qui se passe dans la pile

    Citation Envoyé par alexgpx Voir le message
    J'aurai une petite question, concernant la taille de la pile. A priori je ne connais pas la taille de ma pile de pixel mais en sachant que mon calque est un tableau 2D de même hauteur et largeur, est ce que lors de l'initialisation de ma pile, si j'écris, en reprenant mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* creation d'une structure de pile qui va contenir les differentes pixels*/
    struct stack_pixel{
        pixel *taille; // je n'écris pas taille[] car je ne connais pas le nombre exact de pixel que pourrait contenir ma pile
        int top;
    };
    typedef struct stack_pixel stack_pixel;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    /* initialisation d'une pile */
    stack_pixel create_empty_stack_pixel(int taille_calque){ // je mets comme argument la taille du calque
        stack_pixel r;
        r.taille[taille_calque*taille_calque]; // ma pile peut donc contenir taille_calque*taille_calque pixel 
        r.top=-1;
        return r;
    }
    Oui, et non.

    Oui parce qu'effectivement tu as le droit de supposer que tes datas ne dépasseront pas une certaine taille (faut tout de même bien lire l'énoncé car ça peut être mentionné)

    Non parce qu'on ne crée pas de tableau de n en disant simplement tab[n]. Ca ce n'est pas une instruction de création de tableau mais une instruction disant que tu veux traiter la case "n" de tab. On crée un tableau de n via une allocation dynamique qui passe par malloc (d'où mon exemple). Si tu ne veux pas créer de tableau par allocation lors de l'exécution alors tu ne peux le créer que de façon statique en lui mettant une taille fixée au départ.

    Citation Envoyé par alexgpx Voir le message
    Ou bien est-ce qu'il est tout de même préférable d'avoir une pile dynamique ? Je ne sais pas ce qui pourrait se passer à ma pile si j'ai une image de taille 1000x1000 par exemple, ma pile pourra accueillir 1000x1000 pixel ?
    C'est ce qu'on nomme le rapport "risque/coût en codage pour y pallier". Si tu estimes le risque d'avoir un calque plus grand que X*Y plus que négligeable tu peux alors assumer le risque et partir sur un tab[X*Y].
    Mais attention toutefois car ce point de vue ne peut pas s'étendre à l'infini car un tableau statique est défini dans la pile qui a une taille limitée. Toi tu parles de 1000*1000 donc un million et ici on parle d'un million de pixels qui sont composés de 3 couleurs et une opacité (donc 4 sous-types qui sont des "composantes"). Donc dans le meilleur des cas 4 caractères (parce que tu n'as pas montré ce qu'était une composante mais elle ne peut pas faire moins d'un char) soit donc au final tab faisant (au mieux) 4 millions de caractères. C'est très très très limite...

  7. #7
    Candidat au Club
    Homme Profil pro
    étudiant
    Inscrit en
    Décembre 2022
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : étudiant

    Informations forums :
    Inscription : Décembre 2022
    Messages : 7
    Points : 3
    Points
    3
    Par défaut
    D'accord je vois ! Je vous remercie d'avoir pris le temps de m'expliquer tout ça et en plus de m'avoir donné des exemples tapés !
    Je vais donc passer par une pile dynamique pour mon algo de remplissage

    Et pour l'algo de remplissage, est-ce que le raisonnement est correcte ? ( en supposant que j'ai une pile correcte ) Tout ce qui est partie if etc..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    void fill_using_stack(int x0,int y0, calque *calque,pixel nouveau,int taille_calque){
     
     
        /************************************************************************/
        // j'intialise ma pile de pixel
     
        stack_pixel r; 
        pixel px_comparaison;
        r=create_empty_stack_pixel();
        // j'ajoute le premier pixel de mon calque à la position (x0,y0) dans la pile
     
        if(comparaison_pixel(calque->tab[y0][x0],nouveau)==0){
            return;
        }
        push_pixel(calque->tab[y0][x0],&r);
     
        // j'initialise les cordonnées (x,y) du 1er pixel
        int x,y;
        x=x0;
        y=y0;
        //boucle while sur la pile: condition d'arrêt lorsque la pile est vide
     
        while(!is_empty_stack_pixel(r)){
            // j'enlève un pixel de la pile 
            px_comparaison=pop_pixel(&r);
     
            // je remplace le pixel dans la pile par le nouveau pixel
            set_pixel(&px_comparaison,nouveau);
            // puis je le mets dans le calque à sa position 
            set_calque_pixel(x,y,calque,px_comparaison);
            // condition sur la coordonée y pour éviter un dépassement du calque ( tableau à 2D )
            if(y>0){
                // je compare le pixel au nord avec le pixel de remplacement ( nouveau )
                if(comparaison_pixel(calque->tab[y-1][x],nouveau)==0){ // si c'est = 0 ça veut dire que les 2 pixels sont différents
                push_pixel(calque->tab[y-1][x],&r); // dans ce cas mets le pixel au nord dans la pile 
                }
                // je décrémente ma coordonée y pour me déplacer au nord
                y=y-1;
            }
     
            /*même idée pour les autres coordonées : pixel nord,est,ouest */
            if(y<taille_calque-1){
                if(comparaison_pixel(calque->tab[y+1][x],nouveau)==0){
                push_pixel(calque->tab[y+1][x],&r);
                }
                y=y+1;
            }
            if(x<taille_calque-1){
                if(comparaison_pixel(calque->tab[y][x+1],nouveau)==0){
                push_pixel(calque->tab[y][x+1],&r);
                }
                x=x+1;
            }
            if(x>0){
                if(comparaison_pixel(calque->tab[y][x-1],nouveau)==0){
                push_pixel(calque->tab[y][x-1],&r);
                }
                x=x-1;
            }
     
     
        }
     
    }
    honnêtement je n'arrive pas à reproduire la partie avec les if de l'algo de remplissage de wikipédia avec mon calque :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    remplissage4(pixel, colcible, colrep)
     début
       Soit P une pile vide
       si couleur(pixel) ≠ colcible alors sortir finsi
       Empiler pixel sur P
       Tant que P non vide
       faire
         Dépiler n de P
         couleur(n) ← colrep
         si couleur(n nord) = colcible alors Empiler n nord sur P finsi
         si couleur(n sud)  = colcible alors Empiler n sud  sur P finsi
         si couleur(n est)  = colcible alors Empiler n est  sur P finsi
         si couleur(n ouest)= colcible alors Empiler n ouest sur P finsi
       fintantque
     fin
    comment à partir du pixel que je récupére avec pop je peux me "déplacer" au nord, sud, est, ouest ? Peut-être faudrait il que j'ajoute une variable "position" à ma structure de pixel ? comme ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    /* structue pour un pixel */
    struct pixel{
        couleur c;
        opacite o;
        position pos;
    };
    typedef struct pixel pixel;
    Puis je fais des choses avec pos ??

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 735
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 735
    Points : 31 060
    Points
    31 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par alexgpx Voir le message
    comment à partir du pixel que je récupére avec pop je peux me "déplacer" au nord, sud, est, ouest ? Peut-être faudrait il que j'ajoute une variable "position" à ma structure de pixel ? comme ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    /* structue pour un pixel */
    struct pixel{
        couleur c;
        opacite o;
        position pos;
    };
    typedef struct pixel pixel;
    Puis je fais des choses avec pos ??
    Pourquoi alors stocker un pixel dans la pile? Pourquoi ne pas simplement stocker la position???
    Tu travailles alors avec uniquement des positions et avec cette position + le calque tu as le pixel...

  9. #9
    Candidat au Club
    Homme Profil pro
    étudiant
    Inscrit en
    Décembre 2022
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : étudiant

    Informations forums :
    Inscription : Décembre 2022
    Messages : 7
    Points : 3
    Points
    3
    Par défaut
    Ok ok je vois, j'étais parti sur ça au tout début mais j'avais des doutes !
    En tout cas je vous remercie beaucoup pour vôtre patience et vôtre pédagogie !

Discussions similaires

  1. [Débutant] procédure vb.net de remplissage plusieurs combobox
    Par Ys6BcinMZrSO dans le forum Windows Forms
    Réponses: 0
    Dernier message: 08/06/2012, 22h20
  2. Réponses: 9
    Dernier message: 15/10/2007, 11h20
  3. ProgressBar avec plusieurs procédures
    Par elifqaoui dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 08/09/2002, 19h03
  4. [Comparatif] Procédures stockées, triggers, etc.
    Par MCZz dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 28/08/2002, 13h27
  5. Procédure avec un nombre variable d'arguments
    Par charly dans le forum Langage
    Réponses: 15
    Dernier message: 21/06/2002, 12h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo