Algorithme d'Angres et dégradé chromatique

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

Salut à tous,

Ce que je voudrais faire

Je dispose de l'algorithme de tracé de cercle d'Andres et d'un algorithme permettant de créer un dégradé chromatique (ie. : arc-en-ciel). Je souhaiterais mettre en relation ces deux algorithmes, c'est-à-dire tout simplement tracer un dégradé chromatique rendu circulaire en utilisant Andres. J'ai déjà fait ça mais en utilisant la formule des équations paramétriques.

Cercle chromatique - Equations paramétriques

Problème

Le souci c'est que je ne vois pas quelles données envoyer de l'algo d'Andres vers l'algo de dégradé. Ce dernier accepte 2 entrées :

  1. L'avancement (pour un dégradé rectangulaire de la gauche vers la droite, ça correspond aux différentes abscisses) ;
  2. Le maximum (dans ce même exemple, ça correspond à la largeur totale du rectangle).

Je précise également deux choses :

  • Il faut tracer un cercle de largeur au moins égale à 1 (pour ce faire, je trace plusieurs cercles qui s'emboîtent, chacun de largeur 1) ;
  • Je ne comprends pas l'algorithme d'Andres, je vois juste qu'il trace 8 octants, par symétrie.

Voilà, je vous remercie d'avance zestueusement !

Sources

Algorithme d'Andres

 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
for(double current_thickness = 0; current_thickness < this.thickness; current_thickness++) {
    w = 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(d - this.circle_gradation_beginning, w - this.circle_gradation_beginning);
        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(d - this.circle_gradation_beginning, w - this.circle_gradation_beginning);
        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(d - this.circle_gradation_beginning, w - this.circle_gradation_beginning);
        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(d - this.circle_gradation_beginning, w - this.circle_gradation_beginning);
        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(d - this.circle_gradation_beginning, w - this.circle_gradation_beginning);
        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(d - this.circle_gradation_beginning, w - this.circle_gradation_beginning);
        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(d - this.circle_gradation_beginning, w - this.circle_gradation_beginning);
        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(d - this.circle_gradation_beginning, w - this.circle_gradation_beginning);
        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;

Algorithme du dégradé chromatique

(sera rendu un petit peu plus lisible très prochainement)

 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

Bonsoir,

L'algorithme de tracé d'Andres permet d'itérer sur les points le long d'un cercle, mais qui parcourt simultanément 8 arcs de cercles (car ces arcs sont symétriques selon des droites particulières : axe des ordonnées, axe des abscisses, et droite d'équation $y = x$).

Ainsi, tu connais les coordonnées $(x, y)$ de chaque point de ton cercle, à partir desquelles tu peux identifier les coordonnées polaires, dont l'angle te servira comme coefficient pour ton dégradé.

Heum aurais-tu un indice à me donner pour savoir comment calculer l'angle associé à la coordonnée (x;y) s'il te plaît ?

Utilise de la trigonométrie dans un triangle rectangle formé par l'origine $(0,0)$, le point $(x,0)$ et le point $(x,y)$.

+0 -0

Il vaut mieux que je calcule moi-même la tangente ou que j'utilise la variante proposée par blo yhg ?

Lern-X

Tu n'as strictement aucun intérêt à calculer la tangente (ou plutôt l’arc-tangente dans ton cas) toi-même puisque c'est de toute façon exactement ce que fait arctan2 sous le capot.

L'idée de mon post, c'était que tu trouves toi même l'idée d'utiliser arc tangente, mais le suspense a été quelque peu ruiné…

+1 -0

D'ailleurs pourquoi faut-il d'abord passer l'ordonnée en paramètre, c'est une raison historique ?

Est-ce que tu as écris le calcul ? Tu devrais comprendre pourquoi.

+0 -0

Heum à part la relation $cos \theta = \frac{coteAdjacent}{hypotenuse}$, je ne vois pas quelle autre relation trigonométrique utiliser dans un triangle-rectangle ? Je sais qu'il y a aussi le sin et la tan, mais ce qui m'intéresse c'est l'angle qui désigne l'écart entre le point du cercle et l'axe des abscisses non ?

Et surtout, je ne comprends pas pourquoi je devrais m'intéresser au cos de cet angle plutôt qu'à… cet angle lui-même ? :o

+0 -0

Je sais qu'il y a aussi le sin et la tan, mais ce qui m'intéresse c'est l'angle qui désigne l'écart entre le point du cercle et l'axe des abscisses non ?

Et alors ? Pourquoi ne pas utiliser la tangente avec l'angle qui t'intéresse ?

Et surtout, je ne comprends pas pourquoi je devrais m'intéresser au cos de cet angle plutôt qu'à… cet angle lui-même ? :o

Là tu m'inquiètes un peu… C'est quelque chose que tu es censé avoir vu au collège, réutilisé au lycée et très probablement encore à la fac si tu y es déjà… Si tu a le cosinus d'un angle, retrouver l'angle en question n'est pas difficile, il suffit d'utiliser la fonction réciproque à la fonction cosinus, qui n'est autre que la fonction arc-cosinus…

+0 -0

Oui j'ai fait de la trigo au collège, mais au lycée ça a été supprimé, et à la fac j'ai dû en faire un mois ou deux, sauf que c'était catastrophique (pour toute la promo)…

Heum si j'utilise le cosinus, ça donne donc : $cos A = \frac{adjacent}{hypoténuse}$ donc $A = arcos \frac{adjacent}{hypoténuse}$ . Bon pour l'instant j'imagine que je ne me trompe pas.

+0 -0

Tu ne dois pas être bien concentré parce que tu avais bon tout à l'heure et tu as inversé la fraction entre temps… Bref.

Maintenant, fais la même chose, mais avec la tangente de l'angle qui t'intéresse au lieu du cosinus. Puis exprime les côtés du triangle en fonction de $x$ et $y$. Tu devrais comprendre facilement pourquoi on préfère utiliser l'arc-tangente et d'où vient l'ordre des arguments.

+0 -0

Tu ne dois pas être bien concentré parce que tu avais bon tout à l'heure et tu as inversé la fraction entre temps… Bref.

Tu as tout à fait raison, j'ai édité d'ailleurs, excuse-moi.

Du coup voici ce que j'ai trouvé. En notant $X$ le point $(x;y)$, $O$ le centre du cercle et extrémité du triangle-rectangle de coordonnées $(0;0)$ et $D(x, 0)$ :

$$ tan(\theta) = \frac{XD}{OX} \Longleftrightarrow tan(\theta) = \frac{y_2 - y_1}{\sqrt{OD² + XD²}} \\ tan(\theta) = \frac{XD}{OX} \Longleftrightarrow tan(\theta) = \frac{y_2 - y_1}{\sqrt{(x_2 - x_1)² + (y_2 - y_1)²}} $$

Ainsi :

$\theta = arctan \frac{y_2 - y_1}{\sqrt{(x_2 - x_1)² + (y_2 - y_1)²}}$

C'est correct ?

+0 -0

Tu parles d'un point $D$ mais tu introduit un point $C$ dans tes formules, et ensuite tu mets des $x_i$ et $y_i$ sans expliquer leur sens… Donc je ne sais pas si c'est correct (mais ça n'en a pas vraiment l'air puisque $OX$ n'est pas censé apparaître dans la tangente de l'angle qui t'intéresse…).

+0 -0

Rarf c'est parce que j'ai écrit $C$ sur mon brouillon, du coup j'ai mal recopié du papier vers MathJax… =/

La racine carrée du dénominateur, c'est la longueur de l'hypoténuse $OX$ en fait.

$y_2 - y_1$ correspond à la longueur $XD$ ; $x_2 - x_1$ correspond à la longueur $OD$.

Donc trois choses :

  • l'hypothénuse n'intervient pas dans la tangente ;
  • les longueurs peuvent être exprimées plus simplement directement en fonction de $x$ et $y$, pas besoin d'introduire de nouvelles variables dans le problème ;
  • détends toi et prends de l'assurance, c'est un exercice simple que je suis sûr que tu peux réaliser entièrement sans avoir à me demander à chaque étape si ce que tu as fait est bon ou non, j'ai l'impression en regardant tes autres sujets que tu te fais une montagne du moindre petit problème que tu rencontres parce que tu te précipites vers ce que tu penses être une solution à ce petit problème et en faisant ça tu fais plein de petites erreurs. Respire un bon coup, et réfléchis calmement. Il n'y a aucune raison pour que tu rames pendant des heures là-dessus si tu prends simplement 30 secondes pour réfléchir avant de foncer tête baissée vers la première presque-solution à laquelle tu penses.
+0 -0

Ah mais oui mais c'est fou, je ne sais pas pourquoi j'ai utilisé l'hypoténuse… J'ai dû aller trop vite et m'emmêler les pinceaux sans m'en rendre compte avec le SOH CAH TOA…

Du coup :

$$ tan(\theta) = \frac{XD}{OD} \Leftrightarrow tan(\theta) = \frac{y}{x} \\ tan(\theta) = \frac{XC}{OC} \Leftrightarrow \theta = arctan(\frac{y}{x}) $$

Et du coup oui je comprends bien pourquoi on donne $y$ en premier paramètre, et pourquoi on utilise $arctan$ !

N'empêche que j'ai honte de mes posts précédents, ça m'apprendra à ne pas me relire/ne pas être suffisamment concentré......

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