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

 Java Discussion :

Triangle Graphique avec longueur en paramètre


Sujet :

Java

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2020
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2020
    Messages : 8
    Points : 8
    Points
    8
    Par défaut Triangle Graphique avec longueur en paramètre
    Bonjour, je souhaite créer un triangle graphique avec les longueurs de ces cotés saisi par un utilisateur.
    Le triangle afficher devra correspondre aux mesures saisi.
    Pour tracer le triangle j'utilise path2D.Double et les fonction moveTo,LineTo.
    Mon problème est que si je place mon premier point aux coordonnés X=10, Y=20, Comment placer correctement mon second point en fonction de la taille du segment et de l'angle former, même problème pour le troisième point.
    Merci

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Reprenons les choses calmement, et équipe toi :
    • d'une feuille de papier
    • d'un crayon
    • d'une règle
    • d'un compas
    • d'un rapporteur (pour la suite)

    Parce que tu vois, si tu comprends comment faire sur papier tu comprendras assez rapidement comment faire sur écran.

    Les choses dont tu disposes :
    • les coordonnées d'un des sommets A x1, y1
    • les longueurs des 3 cotes d1, d2 et d3.


    Maintenant on va commencer a dessiner le triangle :
    1. Place le point A sur ta feuille en (x1, y1).
    2. Tire une droite horizontale et place le point B en (x2, y2).
      On a donc déjà :
      • x2 = x1 + d1;
      • y2 = y1;
    3. Prend ton compas
    4. Trace un cercle de rayon d2 centre sur B
    5. Trace un cercle de rayon d3 centre sur A
    6. Si tes valeurs sont bonnes, tes 2 cercles se croisent a 2 endroits différents, tu peux prendre n'importe lequel des 2 comme point C.


    On peut donc en déduire que x3 et y3 résolvent le système suivant :
    • l’équation du cercle de rayon d2 centre sur B
    • l’équation du cercle de rayon d3 centre sur A


    Tu peux donc en déduire l’équation nécessaire pour résoudre les valeurs possibles de x3 et y3 et la coder, ce qui te permettra de dessiner le point a l’écran.

    Maintenant qu'est ce qui se passe si A et B ne sont pas sur une droite horizontale ? Par exemple le segment [AB] forme un angle de 38° avec l'horizontale
    C'est super facile en fait !!!!

    A nouveau on commence a dessiner le triangle :
    1. Place le point A sur ta feuille en (x1, y1).
    2. Fait tourner ta feuille de papier de -38°
    3. Tire une droit horizontale et place le point B en (x2, y2).
      On a donc déjà :
      • x2 = (x1 + d1) dans le repère de la rotation;
      • y2 = y1 dans le repère de la rotation;
    4. Prend ton compas
    5. Trace un cercle de rayon d2 centre sur B
    6. Trace un cercle de rayon d3 centre sur A
    7. Si tes valeurs sont bonnes, tes 2 cercles se croisent a 2 endroits différents, tu peux prendre n'importe lequel des 2 comme point C.
    8. Fait tourner ta feuille de papier de 38°
    9. Bingo tu as de nouveau un triangle sauf que cette fois-ci il est incline !


    Qu'est ce qu'on peut voir ? Qu'en fait c'est exactement la même solution qu'avant avec juste 2 transformations affines (ici des rotations donc des transformations qui préservent le parallélisme). Et le cœur de la solution reste le même, x3 et y3 résolvent le système suivant :
    • l’équation du cercle de rayon d2 centre sur B
    • l’équation du cercle de rayon d3 centre sur A


    Faut juste arriver a calculer correctement les valeurs de x2 et y2 dans ton repère d'origine en fait. Et si mes souvenirs de trigonométrie d'il y a 40 ans ainsi que de Java2D d'il y a 15 ans ne sont pas trop rouilles ça doit donner un truc du genre :
    • x2 = x1 + d1 * cos(angle)
    • y2 = y1 + d1 * sin(angle)


    Ce qui nous permet de retomber sur la valeur du premier exemple quand on supposait que [AB] était un segment horizontal car cos(0) = 1 et sin(0) = 0.

    Rappel : généralement sur papier on a l'axe Y qui part vers le haut, sur écran il part vers le bas.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par bouye Voir le message
    Faut juste arriver a calculer correctement les valeurs de x2 et y2 dans ton repère d'origine en fait. Et si mes souvenirs de trigonométrie d'il y a 40 ans ainsi que de Java2D d'il y a 15 ans ne sont pas trop rouilles ça doit donner un truc du genre :
    • x2 = x1 + d1 * cos(angle)
    • y2 = y1 + d1 * sin(angle)
    Ce ne peut pas être aussi simple parce que, dans 1 espace vectoriel, tu vas travailler avec des matrices 2x2
    Rotating a point about another point (2D), lien stackoverflow en anglais

    If you rotate point (px, py) around point (ox, oy) by angle theta you'll get:
    • p'x = cos(theta) * (px-ox) - sin(theta) * (py-oy) + ox
    • p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy

    Donc voila , c'est à toi de bien choisir tes origines, tes côtés (du style y=constante ou x=constante), parce que 2 triangles peuvent être identiques mais à des transformations près (translation, rotation, symétrie, ...) (<- comprendre, le nombre de calculs à effectuer peut rapidement augmenté)

    Ensuite, ton exercice est assez flou, parce qu'on ne connaît pas à partir de quel point tu vas faire les rotations/ tu as 2 angles sur 3 (mais il me semble que la somme des angles d'1 triangle est égale à 180°)

    Et 1 dernier truc , il me semble que si tu demandes 2 côtés et 2 angles (3 après calculs), tu vas avoir des cas impossibles - mais tu as assez de données pour faire des simples, doubles vérifications.

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut




    Et je parlais bien de (X2, Y2), pas de (X3, Y3)
    Et je rappelle aussi que je pars du point A et pas de n'importe quel autre sommet avec d1.
    Donc je n'ai pas non plus besoin d'une solution certes mathématiquement correcte mais ultra-générique.
    Pour le problème qui a été présenté ici, la trigonométrie de base, le cercle trigonométrique ainsi que, soyons fous, le nombres complexes sont suffisant pour une première approche simpliste du problème.
    Quand tu manipules ta feuille de papier, le centre de ta rotation a aucune importante, le but c'est d'arriver a saisir que si tu dessines tout a partir d'une ligne horizontale le problème est beaucoup plus facile a appréhender ce qui est généralement une bonne manière d'aborder le dessin en Java2D (genre pédagogie simplifiée et tout ça...).

    Mais quand tu dois coder la chose en faisant soit :
    1. du dessin bitmap via les primitives de Graphics2D
    2. soit du dessin vectoriel en utilisant des positionnements absolution de Shape

    et ben, oui, le centre de rotation doit être le point A qu'on a pris comme point de référence pour commencer le dessin.

    La réalisation de 1) est littéralement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    graphics.translate(-x1, -y1);
    graphics.rotate(-alpha);
    [...] dessin de [AB] puis [BC] puis [AC]
    graphics.rotate(alpha);
    graphics.translate(x1, y1);
    aussi implémentable via un truc dans le genre (qui devrait passer OK puisque les 2 transformations sont affines et inversibles).
    Note : ça fait très longtemps que j'ai pas manipulé de transformations affines donc il est possible que je me trompes dans l'ordre de concaténation.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    final var transform = AffineTransform.getTranslateInstance(-x1, -y1).concatenate(AffineTransform.getTranslateInstance(-alpha));
    graphics.setTransform(transform )
    [...] dessin de [AB] puis [BC] puis [AC]
    graphics.setTransform(transform.createInverse());
    Par contre ça ne l'exempt pas de devoir vérifier que son système d’équations a une solution (hé vi si les 2 cercles ne se croisent ou ne se touchent jamais, il n'y a pas de triangle).
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Note : ceci est en aucun cas une solution au problème initial soulevé par MBI85, c'est dire que je ne résout aucunement les coordonnées des 2 autres sommets. Elles sont supposées être déjà solvées à cette etape.

    Ceci est juste une démonstration qu'en fait on se tape complètement de l’équation complètement pour arriver a dessiner un triangle avec n'importe quel orientation.
    Ici j'ai réduit la méthode ROTATE au placement du point C (et de son label) mais en fait j’aurai tout aussi bien pu dessiner l'intégralité du triangle de cette maniere en accumulant des rotations et des anti-rotations. Le seul soucis de cette méthode c'est qu'elle peut accumuler des erreurs si on en abuse trop suite aux défauts de précision des float et double. Pour bien faire il faudra travailler sur des sous-graphics isolées comme ca chaque traitement qu'on fait sur des sous-vues ne dérègle pas l'affichage finale. En bonus la meme chose mais en affichage "vectoriel" (qui ne l'est pas vraiment puisque Java2D c'est presque full bitmap en fait).

    Nom : Untitled.jpg
Affichages : 81
Taille : 81,8 Ko

    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
    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
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    package test.triangle;
     
    import javax.swing.*;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    import java.awt.*;
    import java.awt.geom.Arc2D;
    import java.awt.geom.Ellipse2D;
    import java.awt.geom.Line2D;
    import java.util.Objects;
     
    public final class Main {
        public static void main(final String... args) {
            SwingUtilities.invokeLater(() -> launch(args));
        }
     
        private static final void launch(final String... args) {
            final var canvas1 = new BitmapCanvas();
            final var canvas2 = new BitmapCanvas();
            canvas2.setRenderMethod(BitmapCanvas.RenderMethod.ROTATE);
            final var canvas3 = new GeomCanvas();
            final var angleSlider = new JSlider(0, 360 * 10);
            angleSlider.setMajorTickSpacing(180 * 10);
            angleSlider.setMinorTickSpacing(45 * 10);
            angleSlider.setPaintTicks(true);
            angleSlider.setValue((int) canvas1.getAlpha() * 10);
            angleSlider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    final double value = angleSlider.getValue() / 10d;
                    canvas1.setAlpha(value);
                    canvas2.setAlpha(value);
                    canvas3.setAlpha(value);
                }
            });
            final var d1Slider = new JSlider(100 * 10, 200 * 10);
            d1Slider.setMajorTickSpacing(50 * 10);
            d1Slider.setMinorTickSpacing(10 * 10);
            d1Slider.setPaintTicks(true);
            d1Slider.setValue((int) canvas1.getD1() * 10);
            d1Slider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    final double value = d1Slider.getValue() / 10d;
                    canvas1.setD1(value);
                    canvas2.setD1(value);
                    canvas3.setD1(value);
                }
            });
            final var cxSlider = new JSlider(-300, 300);
            cxSlider.setValue((int) canvas1.getCOffsetX());
            cxSlider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    final double value = cxSlider.getValue();
                    canvas1.setCOffsetX(value);
                    canvas2.setCOffsetX(value);
                    canvas3.setCOffsetX(value);
                }
            });
            final var cySlider = new JSlider(-300, 300);
            cySlider.setValue((int) canvas1.getCOffsetY());
            cySlider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    final double value = cySlider.getValue();
                    canvas1.setCOffsetY(value);
                    canvas2.setCOffsetY(value);
                    canvas3.setCOffsetY(value);
                }
            });
            final var sidePanel = new JPanel();
            sidePanel.setMinimumSize(new Dimension(200, 200));
            sidePanel.setPreferredSize(new Dimension(200, 200));
            sidePanel.setLayout(new BoxLayout(sidePanel, BoxLayout.Y_AXIS));
            sidePanel.add(angleSlider, 0);
            sidePanel.add(d1Slider, 1);
            sidePanel.add(cxSlider, 2);
            sidePanel.add(cySlider, 3);
            final var centerPanel = new JPanel();
            centerPanel.setLayout(new FlowLayout());
            centerPanel.add(canvas1);
            centerPanel.add(canvas2);
            centerPanel.add(canvas3);
            final var main = new JFrame();
            main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            main.getContentPane().setLayout(new BorderLayout());
            main.getContentPane().add(centerPanel, BorderLayout.CENTER);
            main.getContentPane().add(sidePanel, BorderLayout.EAST);
            main.setTitle("Test");
            main.setVisible(true);
            main.pack();
        }
     
        private static abstract class CanvasBase extends JComponent {
            protected final Stroke SOLID_STROKE_0_5 = new BasicStroke(0.5f);
            protected final Stroke DASHED_STROKE_0_5 = new BasicStroke(0.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{3f, 3f}, 0);
            protected final Stroke SOLID_STROKE_1_0 = new BasicStroke(1f);
            protected final String ALPHA_PATTERN = "α = %.2f°";
            protected final String A_LABEL = "A";
            protected final String B_LABEL = "B";
            protected final String C_LABEL = "C";
            protected final String B_PRIME_LABEL = "B'";
            protected final String C_PRIME_LABEL = "C'";
            protected final Color OUTER_CIRCLE_COLOR = Color.LIGHT_GRAY;
            protected final Color TRIANGLE_COLOR = Color.BLACK;
            protected final Color ALPHA_COLOR = Color.GREEN.darker();
            protected final double ALPHA_VISUAL_RADIUS = 15;
            protected final double POINT_VISUAL_RADIUS = 3;
     
     
            public CanvasBase() {
                super();
                setMinimumSize(new Dimension(500, 500));
                setPreferredSize(new Dimension(500, 500));
            }
     
            @Override
            protected void paintComponent(final Graphics g) {
                super.paintComponent(g);
                g.setColor(Color.WHITE);
                g.clearRect(0, 0, getWidth(), getHeight());
            }
     
            private final double ax = 250;
     
            public double getAx() {
                return ax;
            }
     
            private final double ay = 250;
     
            public double getAy() {
                return ay;
            }
     
            private double cOffsetX = 230;
     
            public double getCOffsetX() {
                return cOffsetX;
            }
     
            public void setCOffsetX(final double value) {
                cOffsetX = value;
                repaint();
            }
     
            private double cOffsetY = 100;
     
            public double getCOffsetY() {
                return cOffsetY;
            }
     
            public void setCOffsetY(final double value) {
                cOffsetY = value;
                repaint();
            }
     
            private double alpha = 30;
     
            public void setAlpha(final double value) {
                alpha = value;
                repaint();
            }
     
            public double getAlpha() {
                return alpha;
            }
     
            private double d1 = 100;
     
            public void setD1(final double value) {
                d1 = value;
                repaint();
            }
     
            public double getD1() {
                return d1;
            }
        }
     
        private static final class BitmapCanvas extends CanvasBase {
            private static enum RenderMethod {
                ROTATE,
                FULL_COMPUTE;
            }
     
            public BitmapCanvas() {
            }
     
            private RenderMethod renderMethod = RenderMethod.FULL_COMPUTE;
     
            public void setRenderMethod(final RenderMethod value) {
                renderMethod = Objects.isNull(value) ? RenderMethod.FULL_COMPUTE : value;
                repaint();
            }
     
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                final var g2d = (Graphics2D) g.create();
                try {
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                    g2d.setStroke(SOLID_STROKE_1_0);
                    g2d.setColor(Color.BLUE);
                    g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
                    g2d.setColor(Color.BLACK);
                    g2d.drawString("BITMAP " + renderMethod, 10, getHeight() - 20);
                    final double alphaDegree = getAlpha();
                    final double alphaRadian = Math.toRadians(alphaDegree);
                    final double d1 = getD1();
                    // A.
                    final double x1 = getAx();
                    final double y1 = getAy();
                    // B' & B.
                    final double x21 = x1 + d1;
                    final double y21 = y1;
                    final double x22 = x1 + d1 * Math.cos(alphaRadian);
                    final double y22 = y1 - d1 * Math.sin(alphaRadian); // Invert Y axis for screen.
                    // C' & C.
                    final double x31 = x1 + getCOffsetX();
                    final double y31 = y1 - getCOffsetY(); // Invert Y axis for screen.
                    final double d3 = Math.sqrt(Math.pow(x31 - x1, 2) + Math.pow(y31 - y1, 2));
                    final double betaRadian = - calculateAngle(x1, y1, x31, y31); // Invert Y axis for screen.
                    final double x32 = x1 + d3 * Math.cos(alphaRadian + betaRadian);
                    final double y32 = y1 - d3 * Math.sin(alphaRadian + betaRadian); // Invert Y axis for screen.
                    // Angle label.
                    final double alphaLabelX = x1 + (ALPHA_VISUAL_RADIUS + 5) * Math.cos(alphaRadian / 2);
                    final double alphaLabelY = y1 - (ALPHA_VISUAL_RADIUS + 5) * Math.sin(alphaRadian / 2); // Invert Y axis for screen.
                    // Outer circle.
                    g2d.setColor(OUTER_CIRCLE_COLOR);
                    g2d.setStroke(SOLID_STROKE_0_5);
                    g2d.drawOval((int) (x1 - d1), (int) (y1 - d1), (int) (2 * d1), (int) (2 * d1));
                    // Angle.
                    g2d.setColor(ALPHA_COLOR);
                    g2d.setStroke(SOLID_STROKE_0_5);
                    g2d.fillArc((int) (x1 - ALPHA_VISUAL_RADIUS), (int) (y1 - ALPHA_VISUAL_RADIUS), (int) (ALPHA_VISUAL_RADIUS * 2), (int) (ALPHA_VISUAL_RADIUS * 2), 0, (int) alphaDegree);
                    g2d.setColor(ALPHA_COLOR.darker());
                    final var angleLabel = ALPHA_PATTERN.formatted(alphaDegree);
                    g2d.drawString(angleLabel, (int) alphaLabelX, (int) alphaLabelY);
                    // Reference points
                    g2d.setStroke(DASHED_STROKE_0_5);
                    // B'.
                    g2d.setColor(Color.RED);
                    g2d.drawLine((int) x1, (int) y1, (int) x21, (int) y21);
                    g2d.fillOval((int) (x21 - POINT_VISUAL_RADIUS), (int) (y21 - POINT_VISUAL_RADIUS), (int) (2 * POINT_VISUAL_RADIUS), (int) (2 * POINT_VISUAL_RADIUS));
                    g2d.drawString(B_PRIME_LABEL, (int) x21 + 20, (int) y21);
                    // C'.
                    g2d.setStroke(DASHED_STROKE_0_5);
                    g2d.setColor(Color.BLUE);
                    g2d.drawLine((int) x1, (int) y1, (int) x31, (int) y31);
                    g2d.drawLine((int) x21, (int) y21, (int) x31, (int) y31);
                    g2d.fillOval((int) (x31 - POINT_VISUAL_RADIUS), (int) (y31 - POINT_VISUAL_RADIUS), (int) (2 * POINT_VISUAL_RADIUS), (int) (2 * POINT_VISUAL_RADIUS));
                    g2d.drawString(C_PRIME_LABEL, (int) x31 + 20, (int) y31);
                    // Triangle.
                    g2d.setColor(TRIANGLE_COLOR);
                    g2d.setStroke(SOLID_STROKE_1_0);
                    // A.
                    g2d.fillOval((int) (x1 - POINT_VISUAL_RADIUS), (int) (y1 - POINT_VISUAL_RADIUS), (int) (2 * POINT_VISUAL_RADIUS), (int) (2 * POINT_VISUAL_RADIUS));
                    g2d.drawString(A_LABEL, (int) x1 - 20, (int) y1);
                    // B.
                    g2d.drawLine((int) x1, (int) y1, (int) x22, (int) y22);
                    g2d.fillOval((int) (x22 - POINT_VISUAL_RADIUS), (int) (y22 - POINT_VISUAL_RADIUS), (int) (2 * POINT_VISUAL_RADIUS), (int) (2 * POINT_VISUAL_RADIUS));
                    g2d.drawString(B_LABEL, (int) x22 + 20, (int) y22);
                    // C.
                    switch (renderMethod) {
                        case ROTATE -> {
                            g2d.rotate(-alphaRadian, x1, y1); // Invert Y axis for screen.
                            g2d.drawLine((int) x1, (int) y1, (int) x31, (int) y31);
                            g2d.drawLine((int) x21, (int) y21, (int) x31, (int) y31);
                            g2d.fillOval((int) (x31 - POINT_VISUAL_RADIUS), (int) (y31 - POINT_VISUAL_RADIUS), (int) (2 * POINT_VISUAL_RADIUS), (int) (2 * POINT_VISUAL_RADIUS));
                            // Need another rotation to make label horizontal.
                            g2d.rotate(alphaRadian, x31, y31); // Invert Y axis for screen.
                            g2d.drawString(C_LABEL, (int) x31 + 20, (int) y31);
                            // Undo all rotations in case we need to draw something else.
                            g2d.rotate(-alphaRadian, x31, y31); // Invert Y axis for screen.
                            g2d.rotate(alphaRadian, x1, y1); // Invert Y axis for screen.
                        }
                        default -> {
                            g2d.drawLine((int)x1, (int)y1, (int) x32, (int) y32);
                            g2d.drawLine((int)x22, (int)y22, (int) x32, (int) y32);
                            g2d.fillOval((int) (x32 - POINT_VISUAL_RADIUS), (int) (y32 - POINT_VISUAL_RADIUS), (int) (2 * POINT_VISUAL_RADIUS), (int) (2 * POINT_VISUAL_RADIUS));
                            g2d.drawString(C_LABEL, (int) x32 + 20, (int) y32);
                        }
                    }
                } finally {
                    g2d.dispose();
                }
            }
        }
     
        private static final class GeomCanvas extends CanvasBase {
            public GeomCanvas() {
            }
     
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                final var g2d = (Graphics2D) g.create();
                try {
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                    g2d.setStroke(SOLID_STROKE_1_0);
                    g2d.setColor(Color.CYAN);
                    g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
                    g2d.setColor(Color.BLACK);
                    g2d.drawString("VECTOR", 10, getHeight() - 20);
                    final double alphaDegree = getAlpha();
                    final double alphaRadian = Math.toRadians(alphaDegree);
                    final double d1 = getD1();
                    // A.
                    final double x1 = getAx();
                    final double y1 = getAy();
                    // B' & B.
                    final double x21 = x1 + d1;
                    final double y21 = y1;
                    final double x22 = x1 + d1 * Math.cos(alphaRadian);
                    final double y22 = y1 - d1 * Math.sin(alphaRadian); // Invert Y axis for screen.
                    // C' & C.
                    final double x31 = x1 + getCOffsetX();
                    final double y31 = y1 - getCOffsetY(); // Invert Y axis for screen.
                    final double d3 = Math.sqrt(Math.pow(x31 - x1, 2) + Math.pow(y31 - y1, 2));
                    final double betaRadian = - calculateAngle(x1, y1, x31, y31); // Invert Y axis for screen.
                    final double x32 = x1 + d3 * Math.cos(alphaRadian + betaRadian);
                    final double y32 = y1 - d3 * Math.sin(alphaRadian + betaRadian); // Invert Y axis for screen.
                    // Angle label.
                    final double alphaLabelX = x1 + (ALPHA_VISUAL_RADIUS + 5) * Math.cos(alphaRadian / 2);
                    final double alphaLabelY = y1 - (ALPHA_VISUAL_RADIUS + 5) * Math.sin(alphaRadian / 2); // Invert Y axis for screen.
                    // Outer circle.
                    circle.setFrameFromCenter(x1, y1, x1 - d1, y1 - d1);
                    g2d.setColor(OUTER_CIRCLE_COLOR);
                    g2d.setStroke(SOLID_STROKE_0_5);
                    g2d.draw(circle);
                    // Angle.
                    arc.setAngleStart(0);
                    arc.setArcByCenter(x1, y1, ALPHA_VISUAL_RADIUS, 0, alphaDegree, Arc2D.PIE);
                    g2d.setColor(ALPHA_COLOR);
                    g2d.setStroke(SOLID_STROKE_0_5);
                    g2d.fill(arc);
                    g2d.setColor(ALPHA_COLOR.darker());
                    final var angleLabel = ALPHA_PATTERN.formatted(alphaDegree);
                    g2d.drawString(angleLabel, (int) alphaLabelX, (int) alphaLabelY);
                    // Reference points
                    g2d.setStroke(DASHED_STROKE_0_5);
                    // B'.
                    g2d.setColor(Color.RED);
                    line.setLine(x1, y1, x21, y21);
                    g2d.draw(line);
                    circle.setFrameFromCenter(x21, y21, x21 - POINT_VISUAL_RADIUS, y21 - POINT_VISUAL_RADIUS);
                    g2d.fill(circle);
                    g2d.drawString(B_PRIME_LABEL, (int) x21 + 20, (int) y21);
                    // C'.
                    g2d.setColor(Color.BLUE);
                    line.setLine(x1, y1, x31, y31);
                    g2d.draw(line);
                    line.setLine(x21, y21, x31, y31);
                    g2d.draw(line);
                    circle.setFrameFromCenter(x31, y31, x31 - POINT_VISUAL_RADIUS, y31 - POINT_VISUAL_RADIUS);
                    g2d.fill(circle);
                    g2d.drawString(C_PRIME_LABEL, (int) x31 + 20, (int) y31);
                    // Triangle.
                    g2d.setColor(TRIANGLE_COLOR);
                    g2d.setStroke(SOLID_STROKE_1_0);
                    // A.
                    circle.setFrameFromCenter(x1, y1, x1 - POINT_VISUAL_RADIUS, y1 - POINT_VISUAL_RADIUS);
                    g2d.fill(circle);
                    g2d.drawString(A_LABEL, (int) x1 - 20, (int) y1);
                    // B.
                    line.setLine(x1, y1, x22, y22);
                    g2d.draw(line);
                    circle.setFrameFromCenter(x22, y22, x22 - POINT_VISUAL_RADIUS, y22 - POINT_VISUAL_RADIUS);
                    g2d.fill(circle);
                    g2d.drawString(B_LABEL, (int) x22 + 20, (int) y22);
                    // C.
                    line.setLine(x1, y1, x32, y32);
                    g2d.draw(line);
                    line.setLine(x22, y22, x32, y32);
                    g2d.draw(line);
                    circle.setFrameFromCenter(x32, y32, x32 - POINT_VISUAL_RADIUS, y32 - POINT_VISUAL_RADIUS);
                    g2d.fill(circle);
                    g2d.drawString(C_LABEL, (int) x32 + 20, (int) y32);
                } finally {
                    g2d.dispose();
                }
            }
     
            private final Ellipse2D circle = new Ellipse2D.Double();
            private final Arc2D arc = new Arc2D.Double();
            private final Line2D line = new Line2D.Double();
        }
     
        public static double calculateAngle(double x1, double y1, double x2, double y2) throws RuntimeException {
            if (x1 == x2 && y1 == y2) {
                throw new RuntimeException("Value not defined");
            }
            double a = x2 - x1;
            double b = y2 - y1;
            double theta = Math.atan2(b, a);
            // Normalize to [0, 2*PI[
            if (theta < 0) {
                theta += 2 * Math.PI;
            }
            return theta;
        }
    }
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2020
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2020
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Bonjour merci pour vos réponses détaillées, je pense avoir trouvé une solution qui fonctionne
    Bouye grâce a ton algorithme :
    x2 = x1 + d1 * cos(angle)
    y2 = y1 + d1 * sin(angle)
    j'ai les coordonnées du point 2.

    Pour le troisième point j'ai trouvé cette algorithme:
    x−xBy=−accosβ(xB−xA)−acsinβ(yB−yA)

    y−yB=acsinβ(xB−xA)−accosβ(yB−yA)



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Double x2=x1+D1*Math.cos(Radianangle1);
    Double Y2=Y1+D1*Math.sin(Radianangle1);
     
     Double X3=-(D2/D1)*Math.cos(Radianangle2)*(X2-X1)-(D2/D1)*Math.sin(Radianangle2)*(Y2-Y1)+X2;
     Double Y3=(D2/D1)*Math.sin(Radianangle2)*(X2-X1)-(D2/D1)*Math.cos(Radianangle2)*(Y2-Y1)+Y2;
    J'ai testé plusieurs types de triangles,quelconques,équilatérales, le graphique affiché correspond.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2016] Sortir un graphique avec 2 paramètres
    Par Mamyda84 dans le forum IHM
    Réponses: 2
    Dernier message: 13/03/2020, 12h02
  2. Graphique avec séries de données de longueur variable
    Par js777 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 06/03/2020, 11h37
  3. [Débutant] Paramétrer une interface graphique avec des checkboxs
    Par Invité dans le forum Interfaces Graphiques
    Réponses: 3
    Dernier message: 03/07/2014, 12h17
  4. Caractéristique des Graphiques avec Tchart
    Par bidson dans le forum XMLRAD
    Réponses: 5
    Dernier message: 19/01/2004, 11h01
  5. faire des graphiques avec Perl
    Par And_the_problem_is dans le forum Modules
    Réponses: 2
    Dernier message: 16/07/2003, 16h08

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