Java 了解2D图形和旋转、drawRect方法

Java 了解2D图形和旋转、drawRect方法,java,swing,rotation,Java,Swing,Rotation,我试图理解如何使用Graphics 2D类的drawRect(intx,inty,intwidth,intheight)方法和rotate(double theta,double x,double y)方法 我想做的是在一个JPanel上画一个正方形并旋转它(所有这些都是用鼠标完成的)。所以这个过程是-点击1(这将给出点1(P1)的坐标-这是正方形的一个角),移动鼠标(鼠标位置给出点2(P2)的坐标-这是正方形的另一个角),旋转正方形(同样,鼠标位置给出点2的坐标)。单击2(点2通过此单击进行更

我试图理解如何使用Graphics 2D类的drawRect(intx,inty,intwidth,intheight)方法和rotate(double theta,double x,double y)方法

我想做的是在一个JPanel上画一个正方形并旋转它(所有这些都是用鼠标完成的)。所以这个过程是-点击1(这将给出点1(P1)的坐标-这是正方形的一个角),移动鼠标(鼠标位置给出点2(P2)的坐标-这是正方形的另一个角),旋转正方形(同样,鼠标位置给出点2的坐标)。单击2(点2通过此单击进行更新,是正方形的最终静止位置)

我的理解和问题是:

我知道P1.x和P1.y是旋转方法中使用的值。P1是旋转点。我也知道旋转法中的θ是旋转角度

我知道drawRect方法的宽度和高度应该等于正方形,但这就是我开始感到困惑的地方

我的问题是:

1) 在drawRect方法中x和y是什么(以及在JPanel位置的什么位置),我如何根据我的情况计算它们?(我原以为它是正方形的左上角,但如果我将P2拖到左上角,会让人感到困惑)

2) 如何从P1和P2算出θ


(注意:这是任何好处,我使用MouseAdapter方法来处理点击和鼠标移动)

出于好奇,我做了这样的东西

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class RectanglePanel extends JPanel{
    private Point anchorPoint = null;
    private Point intermediatePoint = null;
    private Point finalPoint = null;

    public RectanglePanel(){
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent me){
                if(anchorPoint == null){
                    // first click, set anchor point
                    anchorPoint = me.getPoint();
                }else if(finalPoint == null){
                    // second click, set final point
                    finalPoint = me.getPoint();
                }else{
                    // third click, reset clicks, anchor point, intermediate point and final point
                    anchorPoint = null;
                    finalPoint = null;
                    intermediatePoint = null;
                }
                repaint();
            }
        });
        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseMoved(MouseEvent me){
                if(anchorPoint != null && finalPoint == null){
                    // mouse moved
                    // set intermediate point if anchor point is set and final point is not set yet
                    intermediatePoint = me.getPoint();
                    repaint();
                }
            }
        });
    }

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

        if(anchorPoint != null){
            Graphics2D g2d = (Graphics2D) g;
            g2d.setColor(Color.red);

            Point p = finalPoint != null ? finalPoint : intermediatePoint;

            if(p != null && !p.equals(anchorPoint)){
                // final point or intermediate point is set, and is not same as anchor point
                // draw square

                // calculate angle to rotate canvas
                double angle = -Math.toRadians(45) + Math.atan2(p.y - anchorPoint.y, p.x - anchorPoint.x);
                // width of square, calculated using distance formaula and pythagorus theorem
                // distance formula: distance = sqrt((x1-x2)^2 + (y1-y2)^2)
                // pythagorus for right angled triangle: c^2 = a^2 + b^2
                double width = Math.sqrt(((p.x - anchorPoint.x) * (p.x - anchorPoint.x) + (p.y - anchorPoint.y) * (p.y - anchorPoint.y)) / 2.0);
                // set origin to anchorpoint
                g2d.translate(anchorPoint.x, anchorPoint.y);
                // rotate canvas
                g2d.rotate(angle);

                Rectangle2D rectangle2D = new Rectangle2D.Double(0, 0, width, width);
                // draw square
                g2d.draw(rectangle2D);

                // rotate back canvas
                g2d.rotate(-angle);

                // reset back origin
                g2d.translate(-anchorPoint.x, -anchorPoint.y);
            }else{
                g2d.drawRect(anchorPoint.x, anchorPoint.y, 1, 1);
            }
        }
    }

    public static void main(String [] args){
        final JFrame frame = new JFrame("Rectangle Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 400);
        frame.getContentPane().add(new RectanglePanel());
        SwingUtilities.invokeLater(new Runnable() {
           public void run() {
               frame.setVisible(true);
            }
        });
    }
}
您可以这样实现,以解决您的问题。让我知道这是不是你要找的

步骤:

1) 计算正方形的宽度。你们有点,代表正方形的对角。这两点之间的距离是对角线的长度。因此,考虑两点
(x1,y1)
(x2,y2)
,使用距离公式,对角线长度由下式给出:

diagonal_length * diagonal_length = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)
正方形和对角线的两侧将构成直角三角形。正方形的边长度相等,让正方形的边为
,然后使用毕达哥拉斯定理:

side * side + side * side = diagonal_length * diagonal_length
求解上述两个方程

side  = Math.sqrt(((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)) / 2.0);
2) 计算旋转画布的角度,使第二个点与x轴成45度角,将第一个点作为原点

3) 首先指出原点

4) 旋转画布,使第二个点与x轴成45度角,第一个点是原点。这将使正方形的两个边落在轴上,另两个边平行于轴,因此您可以使用图形绘制方法绘制矩形/正方形

5) 从原点绘制正方形,边长如上计算

6) 将画布反向旋转,使其保持旋转前的状态

7) 将原点重置为原点,与设置原点之前一样


完成了

那是一件高雅的作品。我将认真研究它。伟大的作品梅拉曼!:)您必须将原点设置为锚定点,旋转画布,使第二个点与x轴成45度角,原点位于锚定点。然后使用距离公式和毕达哥拉斯定理,计算正方形的边。