Algorithme d'Angres et dégradé chromatique

Le problème exposé dans ce sujet a été résolu.

L'ordre des paramètres est correct, je donne bien l'ordonnée en premier paramètre et l'abscisse en second. =/

En fait j'obtiens ce cercle (seules les couleurs jaune, vert et orange apparaissent) :

Cercle bogué - Andres

J'ai pensé à un éventuel décentrage du cercle, alors je me suis permis d'ajouter du + img_height/2 à l'ordonnée de chaque octant et du + img_width/2 à leur abscisse, histoire de voir si ça changeait quelque chose mais ce n'est pas le cas (ou alors les changements sont imperceptibles).

Voici le source (l'algorithme qui crée le dégradé n'a pas été changé, lui). Merci encore pour ton aide adri1.

 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
case "Andres' algorithm":

for(double current_thickness = 0; current_thickness < this.thickness; current_thickness++) {
    x = 0;
    y = (int) (radius + current_thickness);
    double d = radius + current_thickness - 1;

    while (y >= x) {
        int octant_1_x = x0 + x, octant_1_y = y0 + y;
        int octant_2_x = x0 + y, octant_2_y = y0 + x;
        int octant_3_x = x0 - x, octant_3_y = y0 + y;
        int octant_4_x = x0 - y, octant_4_y = y0 + x;
        int octant_5_x = x0 + x, octant_5_y = y0 - y;
        int octant_6_x = x0 + y, octant_6_y = y0 - x;
        int octant_7_x = x0 - x, octant_7_y =  y0 - y;
        int octant_8_x = x0 - y, octant_8_y = y0 - x;

        max_counter++;

        double[] rgb_gradation_octant_1 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_1_y, octant_1_x), w);
        updates.add(new Pixel(octant_1_x, octant_1_y, Color.color(rgb_gradation_octant_1[0], rgb_gradation_octant_1[1], rgb_gradation_octant_1[2]))); // octant n°1

        double[] rgb_gradation_octant_2 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_2_y, octant_2_x), w);
        updates.add(new Pixel(octant_2_x, octant_2_y, Color.color(rgb_gradation_octant_2[0], rgb_gradation_octant_2[1], rgb_gradation_octant_2[2])));

        double[] rgb_gradation_octant_3 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_3_y, octant_3_x), w);
        updates.add(new Pixel(octant_3_x, octant_3_y, Color.color(rgb_gradation_octant_3[0], rgb_gradation_octant_3[1], rgb_gradation_octant_3[2])));

        double[] rgb_gradation_octant_4 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_4_y, octant_4_x), w);
        updates.add(new Pixel(octant_4_x, octant_4_y, Color.color(rgb_gradation_octant_4[0], rgb_gradation_octant_4[1], rgb_gradation_octant_4[2]))); // octant n°4

        double[] rgb_gradation_octant_5 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_5_y, octant_5_x), w);
        updates.add(new Pixel(octant_5_x, octant_5_y, Color.color(rgb_gradation_octant_5[0], rgb_gradation_octant_5[1], rgb_gradation_octant_5[2]))); // octant n°5

        double[] rgb_gradation_octant_6 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_6_y, octant_6_x), w);
        updates.add(new Pixel(octant_6_x, octant_6_y, Color.color(rgb_gradation_octant_6[0], rgb_gradation_octant_6[1], rgb_gradation_octant_6[2])));

        double[] rgb_gradation_octant_7 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_7_y, octant_7_x), w);
        updates.add(new Pixel(octant_7_x, octant_7_y, Color.color(rgb_gradation_octant_7[0], rgb_gradation_octant_7[1], rgb_gradation_octant_7[2])));

        double[] rgb_gradation_octant_8 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_8_y, octant_8_x), w);
        updates.add(new Pixel(octant_8_x, octant_8_y, Color.color(rgb_gradation_octant_8[0], rgb_gradation_octant_8[1], rgb_gradation_octant_8[2]))); // octant n°8

        if (d >= 2 * x) {
            d -= 2 * x + 1;
            x++;
            } else if (d < 2 * (radius + thickness - y)) {
            d += 2 * y - 1;
            y--;
            } else {
            d += 2 * (y - x - 1);
            y--;
            x++;
            }

        }
    }

gui.getImageAnimation().setMax(max_counter*8);
break;

EDIT

Voici, pour vous éviter de faire un aller-retour page 1, le code du dégradé (dispo également dans l'OP en fait).

 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
/**
     * Makes a chromatic gradation
     * @param x can be a distance or an angle, it is the progress
     * @param w can be a distance or an angle, it is the maximum
     * @return an array containing the coloured pixel's red 0.0 - 1.0, green 0.0 - 1.0 and blue 0.0 - 1.0
     */
    static double[] chromatic_gradation(double x, double w) {
        double[] rgb = new double[3];
        if(x >= 0 && x < w/6) {
            rgb[0] = 1;
            rgb[1] = 6*x/w;
        }
        if(x >= 0 && x < 2*w/6) {
            rgb[2] = 0;
        }
        if(x >= 2*w/6 && x < 3*w/6) {
            rgb[2] = 6*x/w - 2;
        }
        if(x >= 3*w/6 && x < 5*w/6) {
            rgb[2] = 1;
        }
        if(x >= 5*w/6 && x <= w) {
            rgb[2] = -6*x/w + 6;
        }
        if (x >= w/6 && x < 3*w/6) {
            rgb[1] = 1;
        }
        if(x >= 3*w/6 && x < 4*w/6) {
            rgb[1] = -6*x/w + 4;
        }
        if(x >= 4*w/6 && x <= w) {
            rgb[1] = 0;
        }
        if(x >= w/6 && x < 2*w/6) {
            rgb[0] = -6*x/w + 2;
        }
        if(x >= 2*w/6 && x < 4*w/6) {
            rgb[0] = 0;
        }
        if(x >= 4*w/6 && x < 5*w/6) {
            rgb[0] = 6*x/w - 4;
        }
        if(x >= 5*w/6 && x <= w) {
            rgb[0] = 1;
        }
        return rgb;
    }

+0 -0

Je remarque également que les couleurs changent en fonction du centre du cercle. En effet, si je déplace mon cercle à droite, les couleurs ont tendance à être plutôt rouges, par exemple.

Clairement je suis sûr que c'est parce que l'origine du repère cartésien n'est pas le centre du cercle, mais le point haut-gauche de l'image… Parce que normalement la couleur (donc l'angle trouvé par arctan) ne doit pas dépendre de la position du cercle…

En enlevant x0 et y0 (centre du cercle) dans les appels à Math.atan2, j'obtiens un demi-cercle chromatique.

+0 -0

Clairement je suis sûr que c'est parce que l'origine du repère cartésien n'est pas le centre du cercle, mais le point haut-gauche de l'image… Parce que normalement la couleur (donc l'angle trouvé par arctan) ne doit pas dépendre de la position du cercle…

Lern-X

En effet, la fonction atan2 ne connaît pas le centre de ton cercle, et ne pouvait pas deviner ça pour toi. Cette fonction ne fait que retourner l'angle (coordonnées polaires) d'un point du plan.

En enlevant x0 et y0 (centre du cercle) dans les appels à Math.atan2, j'obtiens un demi-cercle chromatique.

Lern-X

Probablement que tu n'as pas fait attention au fait que les valeurs de retour de la fonction sont comprises dans l'intervalle $ \left] -\pi , \pi \right]$ (donc il y a des valeurs négatives).

C'est bien ça merci à vous deux ! :)

Edit : je souhaiterais, pour finir, pouvoir faire débuter la coloration de mon cercle à tel ou tel endroit de celui-ci ; il faut donc que j'ajoute un décalage. Où me conseillez-vous d'effectuer ce dernier ? Juste avant le while ou dans la définition des octants ?

+0 -0

Je complète mon précédent édit : au final deux solutions s'offrent à moi.

  1. Soit j'arrive à modifier les égalités définissant l'abscisse et l'ordonnée de chaque point d'Andres, de sorte à tourner le cercle d'un degré compris entre 0 et 360°, afin de tourner/décaler par la même occasion le dégradé ;

  2. Soit je modifie l'appel à la fonction qui applique le dégradé, afin de tenir compte du décalage de ce dernier.

Par souci de cohérence1, je souhaiterais opter pour la première solution : modifier l'algo d'Andres afin de dessiner chaque octant en tenant compte d'un angle de rotation du cercle.

1 : c'est en effet ainsi que j'ai procédé avec les équations paramétriques, donc autant faire de même avec Andres.

Pour être sûr d'être compris, voici ce que j'aimerais pouvoir faire. On voit que les dégradés suivants ne débutent pas au même point.

Dégradé commençant à droite

Dégradé commençant en haut à gauche


Les égalités que je dois donc modifier sont situées juste en-dessosu du while, c'est-à-dire :

1
2
3
4
5
6
7
8
9
while (y >= x) {
    double octant_1_x = x0 + x, octant_1_y = y0 + y;
    double octant_2_x = x0 + y, octant_2_y = y0 + x;
    double octant_3_x = x0 - x, octant_3_y = y0 + y;
    double octant_4_x = x0 - y, octant_4_y = y0 + x;
    double octant_5_x = x0 + x, octant_5_y = y0 - y;
    double octant_6_x = x0 + y, octant_6_y = y0 - x;
    double octant_7_x = x0 - x, octant_7_y =  y0 - y;
    double octant_8_x = x0 - y, octant_8_y = y0 - x;

Edit :

Il faudrait donc que j'ajoute un facteur de décalage en x et en y pour chaque octant, sachant que je dispose uniquement d'un angle compris entre 0 et 360° (ce décalage). Je dois ainsi "convertir" cet angle en ce facteur de décalage (plus précisément en deux facteurs : un pour x et un pour y comme je l'ai dit ci-dessus).

OU ALORS je ne modifie pas ces égalités. Mais j'ajoute, au moment de dessiner les points, le décalage (exprimé en radians). Ce qui donnerait :

1
new Pixel(Math.tan(Math.atan(octant_1_x) + circle_gradation_beginning),... // ajout de radians et conversion de tout ça en abscisse (tan = 1/arctan)

Qu'en pensez-vous ?

+0 -0

Parce que l'angle dont tu parles, je l'utilise uniquement au niveau du dégradé si je ne me trompe pas. Or par souci de cohérence, je voudrais décaler le tracé du cercle, pas juste l'application du dégradé sur ce cercle.

Je ne sais pas si je m'exprime clairement, n'hésite pas à poser des questions si ce n'est pas le cas.

 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
case "Andres' algorithm":
    w = 2 * Math.PI;

    for(double current_thickness = 0; current_thickness < this.thickness; current_thickness++) {
        x = 0;
        y = (int) (radius + current_thickness);
        double d = radius + current_thickness - 1;

        while (y >= x) {
            double octant_1_x = x0 + x, octant_1_y = y0 + y;
            double octant_2_x = x0 + y, octant_2_y = y0 + x;
            double octant_3_x = x0 - x, octant_3_y = y0 + y;
            double octant_4_x = x0 - y, octant_4_y = y0 + x;
            double octant_5_x = x0 + x, octant_5_y = y0 - y;
            double octant_6_x = x0 + y, octant_6_y = y0 - x;
            double octant_7_x = x0 - x, octant_7_y =  y0 - y;
            double octant_8_x = x0 - y, octant_8_y = y0 - x;

            max_counter++;

            double[] rgb_gradation_octant_1 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_1_y - y0, octant_1_x - x0) + Math.PI, w);
            updates.add(new Pixel(octant_1_x, octant_1_y, Color.color(rgb_gradation_octant_1[0], rgb_gradation_octant_1[1], rgb_gradation_octant_1[2]))); // octant n°1

            double[] rgb_gradation_octant_2 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_2_y - y0, octant_2_x - x0) + Math.PI, w);
            updates.add(new Pixel(octant_2_x, octant_2_y, Color.color(rgb_gradation_octant_2[0], rgb_gradation_octant_2[1], rgb_gradation_octant_2[2])));

            double[] rgb_gradation_octant_3 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_3_y - y0, octant_3_x - x0) + Math.PI, w);
            updates.add(new Pixel(octant_3_x, octant_3_y, Color.color(rgb_gradation_octant_3[0], rgb_gradation_octant_3[1], rgb_gradation_octant_3[2])));

            double[] rgb_gradation_octant_4 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_4_y - y0, octant_4_x - x0) + Math.PI, w);
            updates.add(new Pixel(octant_4_x, octant_4_y, Color.color(rgb_gradation_octant_4[0], rgb_gradation_octant_4[1], rgb_gradation_octant_4[2]))); // octant n°4

            double[] rgb_gradation_octant_5 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_5_y-y0, octant_5_x-x0) + Math.PI, w);
            updates.add(new Pixel(octant_5_x, octant_5_y, Color.color(rgb_gradation_octant_5[0], rgb_gradation_octant_5[1], rgb_gradation_octant_5[2]))); // octant n°5

            double[] rgb_gradation_octant_6 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_6_y-y0, octant_6_x-x0) + Math.PI, w);
            updates.add(new Pixel(octant_6_x, octant_6_y, Color.color(rgb_gradation_octant_6[0], rgb_gradation_octant_6[1], rgb_gradation_octant_6[2])));

            double[] rgb_gradation_octant_7 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_7_y-y0, octant_7_x-x0) + Math.PI, w);
            updates.add(new Pixel(octant_7_x, octant_7_y, Color.color(rgb_gradation_octant_7[0], rgb_gradation_octant_7[1], rgb_gradation_octant_7[2])));

            double[] rgb_gradation_octant_8 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_8_y-y0, octant_8_x-x0) + Math.PI, w);
            updates.add(new Pixel(octant_8_x, octant_8_y, Color.color(rgb_gradation_octant_8[0], rgb_gradation_octant_8[1], rgb_gradation_octant_8[2]))); // octant n°8

            if (d >= 2 * x) {
                d -= 2 * x + 1;
                x++;
            } else if (d < 2 * (radius + thickness - y)) {
                d += 2 * y - 1;
                y--;
            } else {
                d += 2 * (y - x - 1);
                y--;
                x++;
            }

        }
    }

    gui.getImageAnimation().setMax(max_counter*8);
    break;

Or par souci de cohérence, je voudrais décaler le tracé du cercle, pas juste l'application du dégradé sur ce cercle.

Ah ? Quelle cohérence ? Tu dis vouloir faire partir ton dégradé d'une position différente, fais donc partir ton dégradé d'une position différente. Ton cercle restera un cercle. Pourquoi faire compliqué quand on peut faire simple ?

En fait j'ai déjà construit un dégradé circulaire avec les équations paramétriques et le décalage consistait alors à décaler le tracé du cercle (c'est-à-dire débuter le tracé à tel ou tel endroit), mais l'application du dégradé en soi n'était pas changé.

J'ai pris soin de montrer l'algorithme à la fin de ce message.

Du coup j'aimerais faire la même chose, de préférence si ce n'est pas trop compliqué, avec l'algo d'Anres, quitte à modifier ce dernier. Mais je n'ai pas les compétences mathématiques pour le faire seul en fait =/

Après si vraiment c'est trop compliqué, pas de souci, je veux bien essayer d'agir au niveau de l'application du dégradé et non du tracé du cercle. T'en penses quoi du coup ?

Mon algo de tracé de cercles à base d'équations paramétriques :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
case "Parametric equations":
    w = 2 * Math.PI + circle_gradation_beginning;

    double precision = 0.001;
    for (double current_thickness = 0; current_thickness < this.thickness; current_thickness++) {
        for (double angle = this.circle_gradation_beginning; angle <= w; angle += precision) {
            max_counter++;
            x = (int) ((current_thickness + radius) * Math.cos(angle) + x0);
            y = (int) ((current_thickness + radius) * Math.sin(angle) + y0);
            if (x >= 0 && y >= 0) { // Condition required to make the display faster
                rgb_gradation = PhotoRetouchingFormulas.chromatic_gradation(angle - this.circle_gradation_beginning, w - this.circle_gradation_beginning);
                updates.add(new Pixel(x, y, Color.color(rgb_gradation[0], rgb_gradation[1], rgb_gradation[2])));
            }
        }
    }
    gui.getImageAnimation().setMax(max_counter);
    break;

Après si vraiment c'est trop compliqué, pas de souci, je veux bien essayer d'agir au niveau de l'application du dégradé et non du tracé du cercle. T'en penses quoi du coup ?

C'est pas que c'est trop compliqué (c'est de la trigo de base), c'est juste qu'il n'y a strictement aucun intérêt à modifier le repère plutôt que de simplement faire tourner le dégradé.

La trigo qu'on a utilisé tout à l'heure s'applique uniquement au dégradé, mais apparemment tu m'expliques que les égalités définissant les abscisses et les ordonnées sont elles aussi de la trigo ? Je parle des x0 + x, etc.

Mais ok, je vais plutôt travailler sur le dégradé. Donc si je ne me trompe pas, je dois ajouter le décalage, exprimé en radians et converti en multiple de pi, au premier paramètre de la fonction chromatic_gradation ? Et faire de même, sans le convertir en multiple de pi, au second ?

La trigo qu'on a utilisé tout à l'heure s'applique uniquement au dégradé, mais apparemment tu m'expliques que les égalités définissant les abscisses et les ordonnées sont elles aussi de la trigo ? Je parle des x0 + x, etc.

Déterminer les décalages à faire en $x$ et en $y$ pour faire tourner l'ensemble du cercle nécessiterait de la trigo.

Mais ok, je vais plutôt travailler sur le dégradé. Donc si je ne me trompe pas, je dois ajouter le décalage, exprimé en radians et converti en multiple de pi, au premier paramètre de la fonction chromatic_gradation ? Et faire de même, sans le convertir en multiple de pi, au second ?

Essaye, et tu verras bien, non ? C'est important d'essayer, il n'y aura pas toujours quelqu'un pour te souffler par dessus l'épaule si ce que tu fais est bon ou non.

A vrai dire j'essaie depuis plusieurs jours, par session je dirais de 20 à 30 minutes, de faire ça ; au début je pensais justement décaler le dégradé, ensuite j'ai préféré changer le tracé du cercle.

En tout cas j'ai fait de nouveaux essais pour bouger le dégradé, en ajoutant un décalage compris entre 0 et 360° (mais exprimé en radians) aux deux paramètres de la méthode statique de dégradé, mais je m'aperçois que le rouge ne bouge jamais. Par contre ça "étend" les autres couleurs, tant et si bien que le dégradé s'arrête brusquement1.

1 : en effet,

Dégradé râté - Décalage de 360°

Je continue de réfléchir à la façon de faire.

Edit : m'enfin après je trouve ça bizarre d'ajouter l'angle de décalage au premier paramètre, puisque j'ai déjà ajouté à ce dernier $Math.pi$ étant donné les bornes de la fonction atan2.

+0 -0

Je ne sais pas comment fonctionne ta fonction de dégradé, mais à mon avis, elle devrait recevoir un nombre entre 0 et 1, et retourner la couleur correspondante à cette position dans le dégradé.

Ainsi, la gestion de l'intervalle serait faite en dehors, et tu pourrais lui appliquer toutes les transformations que tu veux (en l'occurrence, une addition, un modulo et une division).

Après concrètement ça ne change rien au problème je pense, c'est plutôt une amélioration que je pourrais apporter un peu plus tard.

L'addition, c'est l'ajout du décalage non ?

Le modulo, c'est pas modulo 2 pi (un tour de cercle) ?

Et la division là par contre… En vrai je galère à trouver une formule… =/

+0 -0

Alors du coup après recherche, j'ai trouvé les formules pour tourner le cercle d'un certain angle (finalement j'ai préféré agir sur les points du cercle et non juste sur le dégradé, toujours par souci de cohérence puisque c'est ainsi que j'ai procédé avec les équations paramétriques).

En effet, je peux obtenir par exemple ces deux cercles :

Dégradé débutant à gauche, angle = 0°

Dégradé débutant en bas, angle > 0°

Mais…

Le problème c'est qu'il y a beaucoup d'imprécision dès que l'angle/le décalage est > 0° : des trous apparaissent et le contour du cercle n'est pas bien délimité (on voit bien ces défauts sur la seconde image).

Du coup si jamais vous avez une idée pour résoudre ce problème, je serais preneur :o

J'ai pensé à des casts qui auraient diminué la précision mais normalement il n'y en a pas.

Sources

Alors pour faire tourner le cercle, j'ai fait une rotation de chaque pixel :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
/**
 * Constructs a Pixel taking account of a shift and near the position (x0 ; y0)
 * @param x
 * @param y
 * @param color
 * @param angle
 * @param x0
 * @param y0
 */
Pixel(double x, double y, Color color, double angle, double x0, double y0) {
    this.x = (int) (x0 + (x-x0) * Math.cos(angle) - (y-y0) * Math.sin(angle));
    this.y = (int) (y0 + (y-y0) * Math.cos(angle) + (x-x0) * Math.sin(angle));
    this.color = color;
}

Je n'ai pas modifié le code de l'algorithme d'Andres (mis à part les appels à ce nouveau constructeur Pixel()), qui reste donc :

 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
case "Andres' algorithm":
    w = 2 * Math.PI;

    for(double current_thickness = 0; current_thickness < this.thickness; current_thickness++) {
        x = 0;
        y = (int) (radius + current_thickness);
        double d = radius + current_thickness - 1;

        while (y >= x) {
            double octant_1_x = x0 + x, octant_1_y = y0 + y;
            double octant_2_x = x0 + y, octant_2_y = y0 + x;
            double octant_3_x = x0 - x, octant_3_y = y0 + y;
            double octant_4_x = x0 - y, octant_4_y = y0 + x;
            double octant_5_x = x0 + x, octant_5_y = y0 - y;
            double octant_6_x = x0 + y, octant_6_y = y0 - x;
            double octant_7_x = x0 - x, octant_7_y =  y0 - y;
            double octant_8_x = x0 - y, octant_8_y = y0 - x;

            max_counter++;

            double[] rgb_gradation_octant_1 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_1_y - y0, octant_1_x - x0) + Math.PI, w);
            updates.add(new Pixel(octant_1_x, octant_1_y,
                    Color.color(rgb_gradation_octant_1[0], rgb_gradation_octant_1[1], rgb_gradation_octant_1[2]),
                    circle_gradation_beginning, x0, y0)); // octant n°1

            double[] rgb_gradation_octant_2 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_2_y - y0, octant_2_x - x0) + Math.PI, w);
            updates.add(new Pixel(octant_2_x, octant_2_y,
                    Color.color(rgb_gradation_octant_2[0], rgb_gradation_octant_2[1], rgb_gradation_octant_2[2]),
                    circle_gradation_beginning, x0, y0));

            double[] rgb_gradation_octant_3 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_3_y - y0, octant_3_x - x0) + Math.PI, w);
            updates.add(new Pixel(octant_3_x, octant_3_y,
                    Color.color(rgb_gradation_octant_3[0], rgb_gradation_octant_3[1], rgb_gradation_octant_3[2]),
                    circle_gradation_beginning, x0, y0));

            double[] rgb_gradation_octant_4 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_4_y - y0, octant_4_x - x0) + Math.PI, w);
            updates.add(new Pixel(octant_4_x, octant_4_y,
                    Color.color(rgb_gradation_octant_4[0], rgb_gradation_octant_4[1], rgb_gradation_octant_4[2]),
                    circle_gradation_beginning, x0, y0)); // octant n°4

            double[] rgb_gradation_octant_5 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_5_y-y0, octant_5_x-x0) + Math.PI, w);
            updates.add(new Pixel(octant_5_x, octant_5_y,
                    Color.color(rgb_gradation_octant_5[0], rgb_gradation_octant_5[1], rgb_gradation_octant_5[2]),
                    circle_gradation_beginning, x0, y0)); // octant n°5

            double[] rgb_gradation_octant_6 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_6_y-y0, octant_6_x-x0) + Math.PI, w);
            updates.add(new Pixel(octant_6_x, octant_6_y,
                    Color.color(rgb_gradation_octant_6[0], rgb_gradation_octant_6[1], rgb_gradation_octant_6[2]),
                    circle_gradation_beginning, x0, y0));

            double[] rgb_gradation_octant_7 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_7_y-y0, octant_7_x-x0) + Math.PI, w);
            updates.add(new Pixel(octant_7_x, octant_7_y,
                    Color.color(rgb_gradation_octant_7[0], rgb_gradation_octant_7[1], rgb_gradation_octant_7[2]),
                    circle_gradation_beginning, x0, y0));

            double[] rgb_gradation_octant_8 = PhotoRetouchingFormulas.chromatic_gradation(Math.atan2(octant_8_y-y0, octant_8_x-x0) + Math.PI, w);
            updates.add(new Pixel(octant_8_x, octant_8_y,
                    Color.color(rgb_gradation_octant_8[0], rgb_gradation_octant_8[1], rgb_gradation_octant_8[2]),
                    circle_gradation_beginning, x0, y0)); // octant n°8

            if (d >= 2 * x) {
                d -= 2 * x + 1;
                x++;
            } else if (d < 2 * (radius + thickness - y)) {
                d += 2 * y - 1;
                y--;
            } else {
                d += 2 * (y - x - 1);
                y--;
                x++;
            }

        }
    }

    gui.getImageAnimation().setMax(max_counter*8);
    break;

Edit (important)

Arf on m'a dit que ce problème n'a pas de solution, et que dès qu'on essaie de modifier un cercle tracé avec Bresenham ou Andres (rotation, etc.), des problèmes d'affichage non-résolubles auront lieu (pixels manquants etc).

Du coup bein retour à la case départ… Et cette fois je vais agir au niveau du dégradé comme vous me l'aviez recommandé et non au niveau des pixels x)

+0 -0

toujours par souci de cohérence puisque c'est ainsi que j'ai procédé avec les équations paramétriques

Lern-X

Le soucis de cohérence, c'est surtout de ne pas changer la manière de tracer ton cercle suivant la couleur que tu veux lui donner.

Pour ton problème, il y a bien évidemment des casts, dans ta classe Pixel, quand tu appliques des sinus et cosinus à tes coordonnées et que tu les stockes dans des variables de type int (ce qui est normal, les coordonnées d'un pixel sont entières).

Oui mais je ne pense pas que ces cast aient causé ces imprécisions de tracé en fait, mais bon je n'en ai pas la preuve…


Edit

Alors du coup j'essaie de modifier l'application du dégradé de la manière suivante :

  1. Je fais la soustraction de l'angle du point en train d'être colorié par l'angle de décalage ;

  2. Ceci me permet d'obtenir l'angle du point situé en-dessous de celui de la puce n°1 ;

  3. Il faut donc un modulo (car on pourrait avoir des valeurs négatives, ce qui donnerait du noir…).

Heum je ne suis pas très à l'aise avec les modulos, est-ce que tu peux m'aider à le trouver s'il te plaît ? =/

+0 -0

Oui mais je ne pense pas que ces cast aient causé ces imprécisions de tracé en fait, mais bon je n'en ai pas la preuve…

Lern-X

Il suffit de petits arrondis pour que deux point initialement distincts se retrouvent confondus après transformations. Si ces points sont confondus, les pixels normalement occupés (s'il n'y avait pas eu d'imprécision) sont libres, et ça forme des trous.

Alors du coup j'essaie de modifier l'application du dégradé de la manière suivante : 1. Je fais la soustraction de l'angle du point en train d'être colorié par l'angle de décalage ; 2. Ceci me permet d'obtenir l'angle du point situé en-dessous de celui de la puce n°1 ; 3. Il faut donc un modulo (car on pourrait avoir des valeurs négatives, ce qui donnerait du noir…).

Heum je ne suis pas très à l'aise avec les modulos, est-ce que tu peux m'aider à le trouver s'il te plaît ? =/

Lern-X

L'angle, tu sais déjà le récupérer depuis les coordonnées polaires. Je ne vois pas bien ce qui te pose problème ensuite.

Tu te moques un peu d'avoir l'angle du point précédent ou suivant sur le cercle. Imagine juste qu'à chaque point du cercle tu as associé un pas du dégradé (de 0 = couleur initiale à 1 = couleur finale). Tu décales ensuite ton dégradé en ajustant le pas de chaque point. Le modulo, c'est simplement parce que ta fonction qui associe une couleur à un pas peut être vue comme périodique.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte