围绕点java旋转三角形

时间:2014-12-02 22:42:15

标签: java swing rotation geometry

我遇到了麻烦。我需要使用拖动侦听器和单击侦听器围绕它的中心旋转等边三角形。三角形应该增长但现在改变角度并且在以三角形的中间为中心的同时旋转一个点。这是我的问题,它当前正在拖动点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();
}

};` 

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

1 个答案:

答案 0 :(得分: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

中的解决方案

例如......

enter image description here

红线很简单,指示三角形的尖端指向鼠标......

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,但这不是你开始的......