围绕点java旋转三角形

我遇到了麻烦。 我需要使用拖动侦听器和单击侦听器围绕它的中心旋转等边三角形。 三角形应该增长但是现在改变角度并且在以三角形的中间为中心的同时旋转一个点。 这是我的问题,它正在拖动点3并围绕点1旋转。我有一个值x和y的数组,它存储4个值,每个值包含初始点在序数值0和点1 2和3 at相应的值。

`

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(); } };` 

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

首先来看看2D图形 ,特别是变换形状,文本和图像 。

基本上,您“多边形”将具有可定义的大小(最大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; 

这是基于这个问题的解决方案

例如...

在此处输入图像描述

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

 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岁的孩子对基础数学有更好的掌握,这是最简单的解决方案我可以提出不会融化我的大脑并使用双arrays多边形API。 就个人而言,我使用Shape API,但这不是你开始的......