Votre avis sur mon cercle chromatique

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Salut !

Après le dégradé horizontal que vous m'avez aidé à construire, voici le cercle chromatique !

J'ai utilisé les mêmes équations pour déterminer la couleur, cette fois-ci en me basant sur des angles et non pas sur des abscisses.

Pour l'instant, je peux choisir le rayon du cercle ainsi que sa largeur. Voici par exemple un cercle de rayon 100px et de largeur 50px :

Cercle chromatique

Les contours internes et externes du cercle sont abrupts, et ceci est dû à mon algorithme (pas au screenshot par exemple !).

Alors évidemment si j'ai créé ce topic c'est que j'ai une ou deux questions à vous poser ! :-°

Concernant l'algorithme actuel

  1. Pour dessiner un cercle de largeur 2px, je dessine deux cercles de largeur 1px dont le rayon est de 1px pour le premier et de 2px pour le second, etc. : est-ce cool ou y a-t-il une manière plus commune et élégante de faire ça ?

  2. Plus j'augmente la largeur, plus le rendu prend du temps à être dessiné : est-ce dû au point n°1 ?

Autres petites questions, générales

Comme je l'ai dit, j'utilise les mêmes équations que pour le dégradé horizontal et ça marche. J'en déduis que :

a. Les équations qui permettent d'obtenir un dégradé arc-en-ciel sont indépendantes de la forme de cet arc-en-ciel (ça paraît évident vu que ces équations sont juste ce qui lie deux couleurs entre elles : rouge et jaune sont liés par le fait que R = 255 tout en augmentant progressivement G, ces équations n'expriment rien d'autre).

b. Elles peuvent prendre comme paramètre des angles mais aussi des pixels (les abscisses du dégradé horizontal, c'est-à-dire non pas des angles mais des positions - je ne sais pas trop comment appeler ça). Est-ce exact ?

c. Conséquemment au point n°b, aurais-je pu selon vous dessiner mon cercle en utilisant non pas les angles mais les "positions/abscisses" comme j'ai fait pour le dégradé horizontal (histoire d'harmoniser la création du dégradé horizontal et celle du cercle) ? J'imagine qu'utiliser des angles pour le dégradé horizontal n'a pas de sens puisqu'un rectangle n'a pas d'angle…

d. Petite précision pour le point n°c : mon algo crée tout cercle en tant qu'une succession d'une multitude de points qui, s'ils sont suffisamment nombreux, donnent l'impression que cette forme discontinue est continue et que c'est donc un cercle fait d'une ligne. Donc le nombre de ces points est largement supérieur au périmètre du cercle. Enfin voilà j'ai l'impression que cette précision est pertinente mais peut-être que j'aurais pu ne pas vous le dire ! :p

Amélioration à apporter

  1. Je souhaiterais pouvoir démarrer le dégradé à l'angle $\frac{3\pi}{2}$ (par exemple). Par définition du cercle chromatique, ce dégradé se finira également à cette angle (enfin à l'angle $\frac{7\pi}{2}$ du coup, puisqu'on fait un tour complet du cercle pour revenir à cet angle - j'ai donc ajouté ${2\pi}$). Pensez-vous que c'est possible sans trop changer mon algo actuel ? Vous auriez une piste ? ^^'

Voilà voilà !

Mon algorithme

Introduction : équation du tracé d'un cercle

J'utilise le plus simple : deux fonctions (une pour les abscisses, une pour les ordonnées) affines faisant usage des fonctions $cos$ et $sin$ appliquées à plein d'angles ($0$, $\frac{\pi}{2}$, $pi$, et plein d'autres) que je multiplie au rayon et que j'ajoute au centre du cercle.

Equations que j'utilise

Après avoir apporté l'amélioration dont je vous ai parlé un peu plus haut, je pense que je créerai une nouvelle version de mon algo, cette fois sans utiliser ces équations. A la place j'essaierai de mettre en place Bresenham.

Le source

Et bien sûr voici mon algo (n'hésitez pas à le critiquer !).

 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
public void displayCircle() {
        double pi = 3.14159;

        double ra = 100, x0 = 200, y0 = 300, x, y;
        double r, g , b;
        double custom_angle = 0;
        double  w = 2*pi;

        for(double width = 0; width < 50; width++) {
            r = 0; g = 0; b = 0;
            for (double angle = custom_angle; angle <= w; angle += 0.00001) {
                x = (width + ra) * Math.cos(angle) + x0;
                y = (width + ra) * Math.sin(angle) + y0;

                if (angle >= 0 && angle < w / 6) {
                    r = 255;
                    g = 1530 * angle / w;
                }

                if (angle >= 0 && angle < 2 * w / 6) {
                    b = 0;
                }

                if (angle >= 2 * w / 6 && angle < 3 * w / 6) {
                    b = 1530 * angle / w - 510;
                }

                if (angle >= 3 * w / 6 && angle < 5 * w / 6) {
                    b = 255;
                }

                if (angle >= 5 * w / 6 && angle <= w) {
                    b = -1530 * angle / w + 1530;
                }

                if (angle >= w / 6 && angle < 3 * w / 6) {
                    g = 255;
                }

                if (angle >= 3 * w / 6 && angle < 4 * w / 6) {
                    g = -1530 * angle / w + 1020;
                }

                if (angle >= 4 * w / 6 && angle <= w) {
                    g = 0;
                }

                if (angle >= w / 6 && angle < 2 * w / 6) {
                    r = -1530 * angle / w + 510;
                }

                if (angle >= 2 * w / 6 && angle < 4 * w / 6) {
                    r = 0;
                }

                if (angle >= 4 * w / 6 && angle < 5 * w / 6) {
                    r = 1530 * angle / w - 1020;
                }

                if (angle >= 5 * w / 6 && angle <= w) {
                    r = 255;
                }

                this.writable_pixel_writer.setColor((int) x, (int) y, Color.color(r / 255, g / 255, b / 255));
            }
        }
    }

Merci d'avance ! :)

Édité par The-Aloha-Protocol

Université de Bretagne-Sud <3

+0 -0

Cette réponse a aidé l'auteur du sujet

En utilisant tes points a. et b., je définirais une fonction qui prend en paramètre un nombre réel entre 0 et 1 et qui retourne la couleur associée au dégradé. 0 retourne rouge, 1/6 jaune et ainsi de suite. Ça te permettra d'utiliser ce même code dans tous tes projets sans mélanger la logique du dégradée et celle de comment le représenter. Au passage, ça devrait te permettre de résoudre ton point 1. en envoyant non pas $\alpha / 2\pi$ mais $\alpha / 2\pi + 3\pi / 2 \mod 1$.

Enfin, venons au dessein du cercle. Ta première idée d'afficher plein de points en changeant l'angle petit à petit n'est pas bête en soit, mais comme tu as pu le voir tu te retrouves à dessiner bien plus de points que ce qui est réellement affiché. En fait, il existe un bon nombre d'algorithmes différents pour tracer un cercle sur un plan discret (un écran). Ils ont chacun certaines propriétés qui peuvent s'avérer utiles suivant ce que tu veux faire de ton cercle. Tu as par example l'algorithme de Bresenham ou celui d'Andres. Ils sont loin d'être triviaux à comprendre, donc tu peux te contenter de regarder un exemple de code et de le copier. Pour ce que tu veux faire, c'est l'algorithme d'Andres qui t'intéresse puisque tu dois tracer un certain nombre de cercles concentriques dont le rayon augmente de 1 pixel à chaque fois (regarde l'image sur les deux articles).

Enfin, pour ton problème de contours abrupts tu as encore plusieurs solutions. La première est d'utiliser une méthode de sur-échantillonnage: tu calcules en mémoire une image x fois plus grande et tu la réduis en utilisant de l'interpolation linéaire ou cubique. Le problème, c'est que ça nécessite beaucoup plus de calculs. Une solution plus simple qui t'évite aussi de t'occuper de l'algo de tracé de cercle est simplement de définir le carré dans lequel ton cercle est et d'itérer sur tous les pixels du carré. Tu peux aisément calculer son angle et sa distance par rapport au centre de ton cercle. Soit il est à l'intérieur de la zone à colorer et tu le colores, soit il est à l'extérieur et tu n'as rien à faire, soit il est à la bordure (à moins d'un pixel de la limite) et dans ce cas, tu fais un mélange de blanc et de la couleur de l'angle. Je te laisse réfléchir à quel proportion de blanc et de couleur il te faut suivant la distance à laquelle tu es de la limite :)

EDIT: Au lieux de redéfinir pi dans ton programme, utilise Math.PI.

Édité par Berdes

+1 -0
Auteur du sujet

Coucou Berdes, merci d'avoir répondu !

D'abord je voudrais résoudre le souci que j'ai évoqué dans la partie "Amélioration à apporter", en minimisant le nombre de modifications à apporter à mon code.

J'ai essayé de trouver une solution il y a trente minutes, après avoir créé le topic. Celle-ci consiste à considérer qu'il y a un décalage (qui peut être nul). Ce décalage est stocké dans la variable shift. J'en tiens compte dans le for, dans les tests et dans les équations.

Je n'ai pas ajouté grand-chose, mais je pensais que tenir compte de ce décalage permettrait de résoudre le problème ; en fait pas du tout.

Voici le code :

 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
double shift = 3*pi/2;
        double  w = 7*pi/2;

        for(double width = 0; width < 5; width++) {
            r = 0; g = 0; b = 0;
            for (double angle = shift; angle <= (w + shift); angle += 0.00001) {
                x = (width + ra) * Math.cos(angle) + x0;
                y = (width + ra) * Math.sin(angle) + y0;

                if (angle >= (0 + shift) && angle < (w / 6 + shift)) {
                    r = 255;
                    g = (1530 * angle / w) + (-1530/w*shift);
                }

                if (angle >= (0 + shift) && angle < (2 * w / 6) + shift) {
                    b = 0;
                }

                if (angle >= (2 * w / 6 + shift) && angle < (3 * w / 6 + shift)) {
                    b = 1530 * angle / w + (-510 - 1530*shift/w);
                }

                if (angle >= (3 * w / 6 + shift) && angle < (5 * w / 6 + shift)) {
                    b = 255;
                }

                if (angle >= (5 * w / 6 + shift) && angle <= (w + shift)) {
                    b = -1530 * angle / w + (1530 + 1530*shift/w);
                }

                if (angle >= (w / 6 + shift) && angle < (3 * w / 6 + shift)) {
                    g = 255;
                }

                if (angle >= (3 * w / 6 + shift) && angle < (4 * w / 6 + shift)) {
                    g = -1530 * angle / w + (1020 + 1530*shift/w);
                }

                if (angle >= (4 * w / 6 + shift) && angle <= (w + shift)) {
                    g = 0;
                }

                if (angle >= (w / 6 + shift) && angle < (2 * w / 6 + shift)) {
                    r = -1530 * angle / w + (510 + 1530*shift/w);
                }

                if (angle >= (2 * w / 6 + shift) && angle < (4 * w / 6 + shift)) {
                    r = 0;
                }

                if (angle >= (4 * w / 6 + shift) && angle < (5 * w / 6 + shift)) {
                    r = 1530 * angle / w + (-1020 - 1530*shift/w);
                }

                if (angle >= (5 * w / 6 + shift) && angle <= (w + shift)) {
                    r = 255;
                }

                this.writable_pixel_writer.setColor((int) x, (int) y, Color.color(r / 255, g / 255, b / 255));
            }
        }

J'ai testé ce source dans deux cas

Avec un décalage nul et la borne max à $2\pi$ ($2\pi$ forcément !)

J'obtiens bien le cercle arc-en-ciel de l'OP ! Donc ça c'est la bonne nouvelle.

Avec un décalage égal à $\frac{3\pi}{2}$ et, du coup, la borne max égale à $\frac{7\pi}{2}$

Là j'obtiens ce truc pas cool (alors que les tests et les équations tenant compte du décalage, je devrais obtenir un cercle arc-en-ciel qui commence et se finit en $\frac{3\pi}{2}$) :

Image utilisateur

Édité par The-Aloha-Protocol

Université de Bretagne-Sud <3

+0 -0

Cette réponse a aidé l'auteur du sujet

Si j'ai un conseil à te donner, c'est bien de séparer ta fonction d'arc-en-ciel. À partir du code que tu as fait pour l'arc-en-ciel sur ton rectangle, écris une fonction qui prend en paramètre un nombre réel entre 0 et 1 et qui retourne l'objet Color qui correspond. Ensuite, modifie ton code pour le cercle afin d'utiliser cette fonction.

Être capable de séparer la logique de deux éléments (ici, la gestion d'un cercle et celle du dégradée) est quelque chose de très important. Ça devrait naturellement régler la majeur partie de tes problèmes au passage :)

Sinon, pour le problème que tu as actuellement, j'ai l'impression que tu as ajouté shift un peu partout alors que l'ajouter uniquement sur la génération des coordonnées x et y aurait suffit. Et vu que tu l'as aussi ajouté à la gestion des couleurs, je suis quasiment sûr que tu t'es trompé quelque part en mélangeant shift et la gestion des couleurs.

+1 -0
Auteur du sujet

Re !

Désolé de cet important retard, j'ai nettoyé en profondeur mon code, ai mieux réparti ce dernier en plusieurs classes…

J'ai également créé, et c'est ce que tu m'avais d'ailleurs conseillé de faire si je ne me trompe pas, la méthode double[] chromatic_gradation(double x, double w) que je pourrais ré-utiliser dans d'autres projets et qui a bien peu de contraintes d'implémentation (pas d'objet Color par exemple).

Du coup je pense que je suis prêt désormais à m'attaquer à ce problème de décalage du dégradé. :pirate:

Sinon, pour le problème que tu as actuellement, j'ai l'impression que tu as ajouté shift un peu partout alors que l'ajouter uniquement sur la génération des coordonnées x et y aurait suffit. Et vu que tu l'as aussi ajouté à la gestion des couleurs, je suis quasiment sûr que tu t'es trompé quelque part en mélangeant shift et la gestion des couleurs.

Je ne veux pas décaler mon cercle en fait (ce qui serait fait si je mettais shift dans la génération de x et y, si je ne m'abuse). Ce que je veux, c'est décaler le dégradé du cercle. C'est-à-dire faire commencer le dégradé à gauche, en haut, en bas, ici, là-bas.

Pour l'instant, mon dégradé commence toujours à droite (puisque le rouge est à droite).

Je dois donc jouer avec les angles et c'est ce que j'essaie de faire… Mais j'ai vraiment du mal. Si tu as une piste, ou quelqu'un d'autre, je serais preneur… !

PS : je suis revenu aux équations sans la variable shift, en effet :

 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;
    }

EDIT : et voici, au cas où, la méthode qui utilise la fonction ci-dessus pour tracer le cercle.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
    private void traceCircularGradation() {
        double w = 2 * 3.141, precision = 0.001;

        int x, y;
        double[] rgb_gradation;
        for (double current_thickness = 0; current_thickness <= this.thickness; current_thickness++) {
            for (double angle = 0; angle <= w; angle += precision) {
                x = (int) ((current_thickness + radius) * Math.cos(angle) + x0);
                y = (int) ((current_thickness + radius) * Math.sin(angle) + y0);
                if(x >= 0 && y >= 0) {
                    rgb_gradation = PhotoRetouchingFormulas.chromatic_gradation(angle, w);
                    updates.add(new Pixel(x, y, Color.color(rgb_gradation[0], rgb_gradation[1], rgb_gradation[2])));
                }
            }
        }
    }

Édité par The-Aloha-Protocol

Université de Bretagne-Sud <3

+0 -0

Cette réponse a aidé l'auteur du sujet

Tu as deux endroits où tu utilises ton angles : dans ton calcul des coordonnées x et y et dans ton calcul de couleur. Pour l'instant, tu utilises le même angle pour les deux, ce qui veux dire que tu vas toujours associer la droite à la couleur rouge. Maintenant, si tu veux associer la gauche à la couleur rouge, il faut qu'un des angles soit égal à l'autre plus $\pi$. À partir de là, avec un peu de réflexion et d'expérimentation tu devrais être capable de bien comprendre.

Autre détail, il serait possible de rendre ton implémentation de gradient chromatique bien plus simple à lire en ayant une condition du style:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const double step = w / 6;
if (x >= 0 && x < step) {
    rgb[0] = 1;
    rgb[1] = x / step;
    rgb[2] = 0;
} else if (x >= step && x < 2 * step) {
    rgb[0] = 1 - (x - step) / step;
    rgb[1] = 1;
    rgb[2] = 0;
} // etc...

Je ne te garanti pas que ce sera plus court, par contre, il sera vraiment beaucoup plus simple à comprendre.

Au passage, j'éviterais de retourner un tableau de double pour la couleur. C'est encore moins bien qu'une classe Color bidon parce que c'est inutilisable directement. Si tu ne veux pas lier ton gradient chromatique à une classe particulière, tu peux faire en sorte que ton gradient chromatique soit générique et retourne une instance d'une interface (en prenant en paramètre une factory). Tu pourra ensuite dans chaque projet implémenter la couleur comme tu veux. Mais ça me semble particulièrement complexe, sachant que je ne vois pas le problème que ton gradient retourne une classe défini juste à côté.

+1 -0

Cette réponse a aidé l'auteur du sujet

Désolé, j'ai mal expliqué. Pour chaque point, tu as un angle défini par sa position et à partir de cet angle, tu dois en déduire une deuxième valeur pour la couleur. En fait, tu ne donnes pas un angle à ta fonction chromatic_gradation, mais une valeur arbitraire que tu calcules à partir d'un angle (dans ton cas, le calcul consiste à retourner l'angle tel quel). Il faut maintenant que tu trouves quel fonction appliquer pour que la couleur corresponde à ce que tu veux. Évidemment, cette fonction prendra en paramètre l'angle du point et l'angle de là où tu veux que le rouge commence. Petite aide: cette fonction est vraiment très simple.

+1 -0
Auteur du sujet

Coucou Berdes, merci d'avoir pris le temps de poster ce message :) .

Je pensais à la fonction $f(ap, ar) = ap + ar$ , avec $ap$ l'angle du point et $ar$ l'angle du RGB (255, 0, 0) (rouge). Mais ça me paraît un peu trop simple… D'autant plus qu'il faudrait peut-être que j'utilise le modulo (pour ramener d'éventuels $4pi$ à $2pi$ (deux tours de cercles)).

Une question me traverse l'esprit : pourquoi ne puis-je pas considérer que l'angle du point est l'angle du rouge ?

Édité par The-Aloha-Protocol

Université de Bretagne-Sud <3

+0 -0

Cette réponse a aidé l'auteur du sujet

Pour la fonction le meilleur moyen de savoir c'est de tester :)

Une question me traverse l'esprit : pourquoi ne puis-je pas considérer que l'angle du point est l'angle du rouge ?

Lern-X

Tout simplement par ce que ce n'est vrai que dans certains cas particuliers. Si tu veux faire varier le vitesse à laquelle la couleur change, ça ne sera plus vrai.

+1 -0
Auteur du sujet

Alors j'ai réussi à faire commencer le rouge tout à gauche, mais sans inventer de fonction (j'ai juste modifié les deux angles angle et w). La fonction que je cherche est censée modifier ces deux angles non ? En tout cas j'avais déjà fait ça en créant ce topic, sans vouloir faire de jeu de mots j'ai l'impression de tourner en rond :p !

Le souci c'est que les couleurs qui vont du rouge au vert sont allongées et le jaune/orange n'apparaissent pas.

Cercle [PI ; 3*PI]

J'ai donc juste changé les bornes et j'ai vérifié à la main pour en être sûr : quand on commence le cercle à $\pi$, et qu'on fait un tour, on arrive bien en $3\pi$. Du coup je ne comprends pas pourquoi mon dégradé s'affiche mal : j'ai l'impression que le problème vient de w. Comme si cette variable n'était pas assez grande… =/

Au cas où, voici le code :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
 double w = 3 * 3.141, precision = 0.001;

        int x, y;
        double[] rgb_gradation;
        long max_counter = 0;
        for (double current_thickness = 0; current_thickness <= this.thickness; current_thickness++) {
            for (double angle = 3.141; 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) {
                    rgb_gradation = PhotoRetouchingFormulas.chromatic_gradation(angle, w);
                    updates.add(new Pixel(x, y, Color.color(rgb_gradation[0], rgb_gradation[1], rgb_gradation[2])));
                }
            }
        }

EDIT

Aaah c'est peut-être une histoire d'unités ! En effet, actuellement je fournis des angles sans unités aux $cos$ et $sin$. Mais si je leur donnes des radians, là ça devrait marcher !

La fonction que tu me demandes de chercher est donc celle qui converti des trucs sans unités (enfin des pixels a priori quand même :o) en radians.

Hey, on est bien d'accord que l'algorithme qui calcule les couleurs du dégradé (donc le code qui possède les nombreuses conditions) ne doit pas être changé, et que seuls ses deux paramètres (angleet w) doivent l'être ? Puisqu'il est indépendant de la forme du dégradé.

Édité par The-Aloha-Protocol

Université de Bretagne-Sud <3

+0 -0

Cette réponse a aidé l'auteur du sujet

En fait, radian n'est pas vraiment une unité. cos et sin prennent bien en paramètre des valeurs sans unités, donc tout va bien.

Si tu regardes ton code, quand tu appelles chromatic_gradation(angle, w), angle varie de $\pi$ à $3\pi$ alors que le premier paramètre est sensé varier de 0 à w.

+1 -0
Auteur du sujet

Désolé, j'allais justement éditer mon post : j'ai ajouté une fonctionnalité d'animation à mon appli qui me permet de voir le cercle se dessiner presqu'en même temps qu'il est calculé. Et du coup je me suis aperçu que son tracé se fait bien, c'est juste la couleur qui ne s'applique pas correctement : j'avais quelques doutes jusque-là ^^'

Si tu regardes ton code, quand tu appelles chromatic_gradation(angle, w), angle varie de $\pi$ à $3\pi$ alors que le premier paramètre est sensé varier de 0 à w.

Oui du coup je me disais bien qu'il fallait diviser un des paramètres par quelque chose (une histoire d'échelle/de proportions a priori).

C'est normal que la borne supérieure de angle soit $3\pi$ (w = $3\pi$) non ? Tu voulais sans doute dire $2\pi$ ? Du coup : "le premier paramètre est censé varier de 0 à $2\pi$)


Edit

Je pense avoir réussi ! Peux-tu me confirmer que c'est bon s'il te plaît ? ^^'

La variable gradation_shift est le point de départ du dégradé (ce que j'appelais incorrectement "décalage", d'ailleurs je pense changer le nom de cette variable).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
    double w = 2 * 3.141 + this.gradation_shift, precision = 0.001;

        int x, y;
        double[] rgb_gradation;
        long max_counter = 0;
        for (double current_thickness = 0; current_thickness < this.thickness; current_thickness++) {
            for (double angle = this.gradation_shift; 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) {
                    rgb_gradation = PhotoRetouchingFormulas.chromatic_gradation(angle-this.gradation_shift, w-this.gradation_shift);
                    updates.add(new Pixel(x, y, Color.color(rgb_gradation[0], rgb_gradation[1], rgb_gradation[2])));
                }
            }
        }

Édité par The-Aloha-Protocol

Université de Bretagne-Sud <3

+0 -0

Cette réponse a aidé l'auteur du sujet

De ce que je vois, ton code semble bon. Par contre, je suis sûr qu'il y a moyen de le simplifier pas mal: au lieux d'ajouter gradation_shift partout pour l'enlever au niveau du calcul de la couleur, il serait plus simple d'uniquement l'ajouter au niveau du calcul de la couleur.

+1 -0
Auteur du sujet

De ce que je vois, ton code semble bon. Par contre, je suis sûr qu'il y a moyen de le simplifier pas mal: au lieux d'ajouter gradation_shift partout pour l'enlever au niveau du calcul de la couleur, il serait plus simple d'uniquement l'ajouter au niveau du calcul de la couleur.

Berdes

Mmmh oui mais ce ne serait pas très pertinent pour un dégradé horizontal ; du coup je pense que je vais essayer de comprendre les algos d'Andres et de Bresenham pour les implémenter. Du coup il y aura trois façons de générer un cercle avec mon petit programme (ces 2-là + les équations paramétriques).

Merci encore pour ton aide ! :)

Édité par The-Aloha-Protocol

Université de Bretagne-Sud <3

+0 -0

Je t'ai mis les liens vers les deux algos, mais seulement celui d'Andres est intéressant dans ton cas puisque celui de Bresenham va laisser des trous dans ton cercle (c.f. l'image de l'article Wikipédia).

+0 -0
Auteur du sujet

Je t'ai mis les liens vers les deux algos, mais seulement celui d'Andres est intéressant dans ton cas puisque celui de Bresenham va laisser des trous dans ton cercle (c.f. l'image de l'article Wikipédia).

Berdes

Justement, je m'étais souvenu de ton message où tu m'avais parlé de ces deux algos ! =P

Et je viens d'implémenter Andres, sauf que justement j'ai des trous qui ne sont a priori pas dus à des cast inopportuns, du coup je me suis permis de créer un topic ^^'

Université de Bretagne-Sud <3

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

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