我试图理解如何使用Graphics 2D类的drawRect(int x,int y,int width,int height)方法和rotate(double theta,double x,double y)方法。
我想要做的是在JPanel上画一个正方形并旋转它(所有这一切都使用鼠标)。所以这个过程就是 - 单击1(这将给出Point 1(P1)的坐标 - 这是方形的一个角),移动鼠标(鼠标位置给出点2(P2)的坐标 - 这是旋转方块(再次,鼠标位置将给出点2的坐标)。点击2(点2通过此点击更新,是广场的最后安息点)
我的理解和问题是:
我知道P1.x和P1.y是rotate方法中使用的值。 P1是旋转点。我也明白旋转方法中的theta是旋转角度。
我知道drawRect方法的宽度和高度应该等于一个正方形,但这是我开始感到困惑的地方。
我的问题是:
1)drawRect方法中的x和y是什么(以及JPanel位置的位置)以及如何根据我的情况进行处理? (我认为它是广场的左上角,但是如果我将P2拖到左上方那就很困惑)
2)如何从P1和P2中计算出θ?
(注意:它有任何好处,我使用MouseAdapter方法来处理点击和鼠标移动)
答案 0 :(得分:4)
出于好奇,我做了类似的事。
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
,然后用pythagorus定理:
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)将原点重置为设置原点之前的原点。
完成!