围绕点java旋转三角形

问题描述 投票:0回答:1

我有麻烦。我需要使用拖动侦听器和单击侦听器围绕其中心旋转等边三角形。三角形应该增加,但现在会改变角度,并以三角形的中心为中心旋转一个点。这是我的问题,它当前正在拖动点3并围绕点1旋转。我有一个值x和y的数组,它存储4个值,每个值包含初始点首先位于序数0处,以及点1 2和3处于相应的值。

`

public class DrawTriangle extends JFrame {

enter code here
/** The Constant NUMBER_3. */
private static final int NUMBER_3 = 3;

/** The Constant EQUL_ANGLE. */
@SuppressWarnings("unused")
private static final double EQUL_ANGLE = 1;

/** The Constant TRIANGLE_POINTS. */
private static final int TRIANGLE_POINTS = 4;

/** The Constant _400. */
private static final int SIZE = 400;

/** The x points. */
private int [] xPoints = new int[TRIANGLE_POINTS];

/** The y points. */
private int [] yPoints = new int[TRIANGLE_POINTS];

private int xInitial;

private int yInitial;

/** The x. */
private double x = EQUL_ANGLE;

/** The new x. */
private double newX;

/** The new y. */
private double newY;

/**
 * Instantiates a new draw triangle.
 */
public DrawTriangle() {
    super("Dimitry Rakhlei");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setContentPane(new DrawTrianglePanel());
    setSize(SIZE, SIZE); // you can change this size but don't make it HUGE!
    setVisible(true);
}

/**
 * The Class DrawTrianglePanel.
 */
private class DrawTrianglePanel extends JPanel implements MouseListener,
        MouseMotionListener {

    /**
     * Instantiates a new draw triangle panel.
     */
    public DrawTrianglePanel() {
        addMouseListener(this);
        addMouseMotionListener(this);
    }

    /**
     * Drawing the triangle.
     *
     * @param g
     *            the g
     * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
     */
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // DRAWING CODE HERE
        g.drawPolygon(xPoints, yPoints, 3);
        System.out.println("Paint called");
    }



    /**
     * (non-Javadoc).
     *
     * @param e
     *            the e
     * @see java.awt.event.MouseListener#mousePressed
     * (java.awt.event.MouseEvent)
     */
    public void mousePressed(MouseEvent e) {
        System.out.println("Mouse pressed called");
        e.getPoint();
        xPoints[0] = e.getPoint().x;
        yPoints[0] = e.getPoint().y;
        repaint();

    }

    /**
     * (non-Javadoc).
     *
     * @param e
     *            the e
     * @see java.awt.event.MouseListener#mouseReleased
     * (java.awt.event.MouseEvent)
     */
    public void mouseReleased(MouseEvent e) {
        System.out.println("Mouse released called");
    }

    /**
     * (non-Javadoc).
     *
     * @param e
     *            the e
     * @see java.awt.event.MouseMotionListener#mouseDragged
     * (java.awt.event.MouseEvent)
     */
    public void mouseDragged(MouseEvent e) {
        System.out.println("Mouse dragged called");
        newX = e.getPoint().x;
        newY = e.getPoint().y;
        xPoints[1] = (int) newX;
        yPoints[1] = (int) newY;


        newX = xPoints[0] + (xPoints[1]-xPoints[0])*Math.cos(x) - (yPoints[1]-yPoints[0])*Math.sin(x);

        newY = yPoints[0] + (xPoints[1]-xPoints[0])*Math.sin(x) + (yPoints[1]-yPoints[0])*Math.cos(x);

        xPoints[2] = (int) newX;
        yPoints[2] = (int) newY;

        newX = xPoints[0] + (xPoints[1]-xPoints[0])*Math.cos(x) - (yPoints[1]-yPoints[0])*Math.sin(x);

        newY = yPoints[0] + (xPoints[1]-xPoints[0])*Math.sin(x) + (yPoints[1]-yPoints[0])*Math.cos(x);

        xPoints[3] = (int) newX;
        yPoints[3] = (int) newY;

        repaint();
    }

    /**
     * (non-Javadoc).
     *
     * @param e
     *            the e
     * @see java.awt.event.MouseListener#mouseEntered
     * (java.awt.event.MouseEvent)
     */
    public void mouseEntered(MouseEvent e) {
        System.out.println("Mouse Entered.");
    }

    /**
     * (non-Javadoc).
     *
     * @param e
     *            the e
     * @see java.awt.event.MouseListener#mouseExited
     * (java.awt.event.MouseEvent)
     */
    public void mouseExited(MouseEvent e) {
        System.out.println("Mouse exited.");
    }

    /**
     * (non-Javadoc).
     *
     * @param e
     *            the e
     * @see java.awt.event.MouseListener#mouseClicked
     * (java.awt.event.MouseEvent)
     */
    public void mouseClicked(MouseEvent e) {
    }

    /**
     * (non-Javadoc).
     *
     * @param e
     *            the e
     * @see java.awt.event.MouseMotionListener#mouseMoved
     * (java.awt.event.MouseEvent)
     */
    public void mouseMoved(MouseEvent e) {
    }

}

/**
 * The main method.
 *
 * @param args
 *            the arguments
 */
public static void main(String[] args) {
    new DrawTriangle();
}

};` 

我的问题是这段代码基本上可以正确运行,但是我被告知旋转的顶点必须在三角形的中间。我的是第一点。

java swing rotation geometry
1个回答
5
投票

首先查看2D Graphics,尤其是Transforming Shapes, Text, and Images

[基本上,您的“多边形”将具有可定义的大小(最大x / y点),由此,您可以确定“多边形”的中心位置,例如...

protected Dimension getTriangleSize() {
    int maxX = 0;
    int maxY = 0;
    for (int index = 0; index < xPoints.length; index++) {
        maxX = Math.max(maxX, xPoints[index]);
    }
    for (int index = 0; index < yPoints.length; index++) {
        maxY = Math.max(maxY, yPoints[index]);
    }
    return new Dimension(maxX, maxY);
}

这只会返回多边形的最大x和y边界。这使您可以计算多边形的中心位置。您将看到为什么在一秒钟之内为什么不需要实际指定原点...

接下来,我们计算一个AffineTransform,它直接应用于Graphics上下文...

Graphics2D g2d = (Graphics2D) g.create();
AffineTransform at = new AffineTransform();
Dimension size = getTriangleSize();
int x = clickPoint.x - (size.width / 2);
int y = clickPoint.y - (size.height / 2);
at.translate(x, y);
at.rotate(Math.toRadians(angle), clickPoint.x - x, clickPoint.y - y);
g2d.setTransform(at);
g2d.drawPolygon(xPoints, yPoints, 3);
// Guide
g2d.setColor(Color.RED);
g2d.drawLine(size.width / 2, 0, size.width / 2, size.height / 2);
g2d.dispose();

这不仅会平移三角形的位置,还会旋转它。这意味着您可以创建一个归一化的多边形(其原点为0x0),并允许Graphics上下文将其放置在所需的位置,这使生活变得如此简单...

现在,旋转计算基于计算两个点之间的角度,即“单击”点和“拖动”点...

angle = -Math.toDegrees(Math.atan2(e.getPoint().x - clickPoint.x, e.getPoint().y - clickPoint.y)) + 180;

基于this question中的解决方案>

例如...

“在此处输入图像描述”

红线是简单的指南,用于显示三角形的尖端指向鼠标...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class DrawTriangle extends JFrame {

    /**
     * The x points.
     */
    private int[] xPoints = new int[]{0, 25, 50};

    /**
     * The y points.
     */
    private int[] yPoints = new int[]{50, 0, 50};

    double angle = 0f;

    /**
     * Instantiates a new draw triangle.
     */
    public DrawTriangle() {
        super("Dimitry Rakhlei");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setContentPane(new DrawTrianglePanel());
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    /**
     * The Class DrawTrianglePanel.
     */
    private class DrawTrianglePanel extends JPanel implements MouseListener,
                    MouseMotionListener {

        private Point clickPoint;

        /**
         * Instantiates a new draw triangle panel.
         */
        public DrawTrianglePanel() {
            addMouseListener(this);
            addMouseMotionListener(this);
            clickPoint = new Point(100, 100);
        }

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

        protected Dimension getTriangleSize() {

            int maxX = 0;
            int maxY = 0;
            for (int index = 0; index < xPoints.length; index++) {
                maxX = Math.max(maxX, xPoints[index]);
            }
            for (int index = 0; index < yPoints.length; index++) {
                maxY = Math.max(maxY, yPoints[index]);
            }
            return new Dimension(maxX, maxY);
        }

        /**
         * Drawing the triangle.
         *
         * @param g the g
         * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
         */
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g.create();
            AffineTransform at = new AffineTransform();
            Dimension size = getTriangleSize();
            int x = clickPoint.x - (size.width / 2);
            int y = clickPoint.y - (size.height / 2);
            at.translate(x, y);
            at.rotate(Math.toRadians(angle), clickPoint.x - x, clickPoint.y - y);
            g2d.setTransform(at);
            g2d.drawPolygon(xPoints, yPoints, 3);
            // Guide
            g2d.setColor(Color.RED);
            g2d.drawLine(size.width / 2, 0, size.width / 2, size.height / 2);
            g2d.dispose();

        }

        /**
         * (non-Javadoc).
         *
         * @param e the e
         * @see java.awt.event.MouseListener#mousePressed (java.awt.event.MouseEvent)
         */
        @Override
        public void mousePressed(MouseEvent e) {
            System.out.println("Mouse pressed called");
            //          clickPoint = e.getPoint();
            repaint();

        }

        /**
         * (non-Javadoc).
         *
         * @param e the e
         * @see java.awt.event.MouseListener#mouseReleased (java.awt.event.MouseEvent)
         */
        @Override
        public void mouseReleased(MouseEvent e) {
            System.out.println("Mouse released called");
        }

        /**
         * (non-Javadoc).
         *
         * @param e the e
         * @see java.awt.event.MouseMotionListener#mouseDragged (java.awt.event.MouseEvent)
         */
        public void mouseDragged(MouseEvent e) {
            System.out.println("Mouse dragged called");

            angle = -Math.toDegrees(Math.atan2(e.getPoint().x - clickPoint.x, e.getPoint().y - clickPoint.y)) + 180;

            repaint();
        }

        /**
         * (non-Javadoc).
         *
         * @param e the e
         * @see java.awt.event.MouseListener#mouseEntered (java.awt.event.MouseEvent)
         */
        public void mouseEntered(MouseEvent e) {
            System.out.println("Mouse Entered.");
        }

        /**
         * (non-Javadoc).
         *
         * @param e the e
         * @see java.awt.event.MouseListener#mouseExited (java.awt.event.MouseEvent)
         */
        public void mouseExited(MouseEvent e) {
            System.out.println("Mouse exited.");
        }

        /**
         * (non-Javadoc).
         *
         * @param e the e
         * @see java.awt.event.MouseListener#mouseClicked (java.awt.event.MouseEvent)
         */
        public void mouseClicked(MouseEvent e) {
        }

        /**
         * (non-Javadoc).
         *
         * @param e the e
         * @see java.awt.event.MouseMotionListener#mouseMoved (java.awt.event.MouseEvent)
         */
        public void mouseMoved(MouseEvent e) {
        }

    }

    /**
     * The main method.
     *
     * @param args the arguments
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                new DrawTriangle();
            }
        });
    }

}

现在,在您跳过我并抱怨解决方案“太复杂”之前,了解我是一个白痴,认真的说,我2岁的孩子比我对基本数学的掌握要好,这是我做得最多的我能想到的简单解决方案不会使我的大脑困惑,而是使用了双数组多边形API。就个人而言,我会使用Shape API,但这不是您开始的目的...

© www.soinside.com 2019 - 2024. All rights reserved.