Java-Calculer et placer l'angle d'une forme géométrique


Je travaille actuellement sur un programme qui permet à l'utilisateur de dessiner diverses formes géométriques. Cependant, j'ai eu quelques problèmes pour calculer et placer les objets d'angle sur mon panneau Canvas avec précision. L'objet angle est essentiellement une extension de l'objet Arc2D, qui fournit une méthode supplémentaire appelée computeStartAndExtent(). Dans ma classe Angle, cette méthode calcule et trouve les valeurs d'angle de départ et d'extension nécessaires:

private void computeStartAndExtent()
    {
        double ang1 = Math.toDegrees(Math.atan2(b1.getY2() - b1.getY1(), b1.getX2() - b1.getX1()));
        double ang2 = Math.toDegrees(Math.atan2(b2.getY2() - b2.getY1(), b2.getX2() - b2.getX1()));

        if(ang2 < ang1)
        {
            start = Math.abs(180 - ang2);
            extent = ang1 - ang2;
        }
        else
        {
            start = Math.abs(180 - ang1);
            extent = ang2 - ang1;
        }
        start -= extent;
    }

C'est un code un peu buggé qui ne fonctionne que lorsque j'en connecte deux lignes les unes aux autres, cependant, lorsque je connecte une troisième pour faire un triangle, le résultat est comme suit,

entrez la description de l'image ici

Comme vous le voyez, l'angle ADB est le seul qui est placé correctement. Je ne pouvais pas comprendre comment surmonter cela. Si vous avez besoin d'informations/de code supplémentaires, veuillez me le faire savoir.

EDIT: b1 et b2 sont des objets Line2D dans la méthode computeStartAndExtent().

Merci.

Author: Burak., 2015-05-06

1 answers

Il y a certaines choses qui peuvent être faites pour simplifier le calcul:

  • Gardez les sommets ordonnés, de sorte qu'il soit toujours clair comment calculer les angles de sommet pointant loin du coin
  • De plus, dessinez toujours le polygone dans la même direction; alors vous pouvez toujours dessiner les angles dans la même direction. L'exemple ci-dessous suppose que le polygone est dessiné dans le sens des aiguilles d'une montre. Le même calcul d'angle entraînerait les arcs dessinés à l'extérieur étant donné un polygone dessiné dans le sens antihoraire.

Exemple de code; n'est pas tout à fait le même que le vôtre car je n'ai pas votre code, mais a des fonctionnalités similaires:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Arc2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Polygon extends JPanel {
    private static final int RADIUS = 20;

    private final int[] xpoints = {
            10, 150, 80, 60
    };
    private final int[] ypoints = {
            10, 10, 150, 60
    };
    final Arc2D[] arcs;

    Polygon() {
        arcs = new Arc2D[xpoints.length];
        for (int i = 0; i < arcs.length; i++) {
            // Indices of previous and next corners
            int prev = (i + arcs.length - 1) % arcs.length;
            int next = (i + arcs.length + 1) % arcs.length;
            // angles of sides, pointing outwards from the corner
            double ang1 = Math.toDegrees(Math.atan2(-(ypoints[prev] - ypoints[i]), xpoints[prev] - xpoints[i]));
            double ang2 = Math.toDegrees(Math.atan2(-(ypoints[next] - ypoints[i]), xpoints[next] - xpoints[i]));
            int start = (int) ang1;
            int extent = (int) (ang2 - ang1);
            // always draw to positive direction, limit the angle <= 360
            extent = (extent + 360) % 360;
            arcs[i] = new Arc2D.Float(xpoints[i] - RADIUS, ypoints[i] - RADIUS, 2 * RADIUS, 2 * RADIUS, start, extent, Arc2D.OPEN);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(160, 160);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.drawPolygon(xpoints, ypoints, xpoints.length);
        Graphics2D g2d = (Graphics2D) g;
        for (Shape s : arcs) {
            g2d.draw(s);
        }
    }

    public static void main(String args[]){
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Polygon");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new Polygon());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

Donne:

Capture d'écran d'un polygone

 1
Author: kiheru, 2015-05-06 12:49:50