我有麻烦。我需要使用拖动侦听器和单击侦听器围绕其中心旋转等边三角形。三角形应该增加,但现在会改变角度,并以三角形的中心为中心旋转一个点。这是我的问题,它当前正在拖动点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();
}
};`
我的问题是这段代码基本上可以正确运行,但是我被告知旋转的顶点必须在三角形的中间。我的是第一点。
首先查看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,但这不是您开始的目的...