- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想了解如何使用 Graphics 2D 类的 drawRect(int x, int y, int width, int height) 方法和 rotate(double theta, double x, double y) 方法。
我想要做的是在 JPanel 上绘制一个正方形并旋转它(所有这些都使用鼠标)。因此,此过程将是 - 单击 1(这将给出点 1 (P1) 的坐标 - 这是正方形的一个角),移动鼠标(鼠标位置给出点 2 (P2) 的坐标 - 这是正方形的对角),旋转正方形(同样,鼠标位置将给出点 2 的坐标)。单击 2(点 2 通过此单击更新,是正方形的最终静止位置)
我的理解和问题是:
我知道 P1.x 和 P1.y 是旋转方法中使用的值。 P1 是旋转点。我也明白rotate方法中的theta是旋转的角度。
我知道 drawRect 方法的宽度和高度应该等于一个正方形,但这是我开始感到困惑的地方。
我的问题是:
1) drawRect 方法中的 x 和 y 是什么(以及在 JPanel 位置方面的位置)以及如何根据我的情况计算出它们? (我以为是正方形的左上角,但是如果我把P2拖到左上角就乱了)
2) 如何从 P1 和 P2 计算出 theta?
(注意:这是什么好处,我正在使用 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 * side = diagonal_length * diagonal_length
求解以上两个方程,
side = Math.sqrt(((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)) / 2.0);
2) 计算旋转 Canvas 的角度,以第一个点为原点,使第二个点与 x 轴成 45 度角。
3) 制作第一点原点。
4) 旋转 Canvas ,使第二点与 x 轴成 45 度角,第一点为原点。这样就可以使正方形的两条边落在坐标轴上,另外两条边与坐标轴平行,这样就可以使用图形的draw方法绘制矩形/正方形。
5) 从原点绘制边长如上计算的正方形。
6) 反向旋转 Canvas ,使其与旋转前一样。
7) 将原点重置为设置原点之前的原点。
完成!
关于java - 了解 Graphics 2D 和旋转、drawRect 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19617924/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!