如何根据给定的度数旋转一条线
How to rotate a line based on a given number of degrees
我用 Graphics 对象绘制了一条线。我想根据拖动鼠标的程度将这条线旋转一定的度数。我可以获得我需要旋转它的度数,但是我如何根据它旋转线?
谢谢!
我想您是在谈论 Java AWT 图形 class。图形可以认为是canvas。它是一个像素值数组,"drawing a line" 只是一个效用函数,它会更改其中一些像素的值 - 从它的角度来看,没有 "line object" 可言。通常你应该擦掉整个东西并用你想要的角度画一条新线。但是为此,您可能需要查看 Graphics2D (http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics2D.html),尤其是 setTransform 和 AffineTransform class.
您可以创建一个 Line2D
object for your original line. Then you can use AffineTransform#getRotateInstance
以获得一个 AffineTransform
,它围绕特定点旋转特定角度。使用此 AffineTransform
,您可以创建一个旋转的 Line2D
对象进行绘制。所以你的绘画代码大概是这样的:
protected void paintComponent(Graphics gr) {
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
// Create the original line, starting at the origin,
// and extending along the x-axis
Line2D line = new Line2D.Double(0,0,100,0);
// Obtain an AffineTransform that describes a rotation
// about a certain angle (given in radians!), around
// the start point of the line. (Here, this is the
// origin, so this could be simplified. But in this
// form, it's more generic)
AffineTransform at =
AffineTransform.getRotateInstance(
Math.toRadians(angleInDegrees), line.getX1(), line.getY1());
// Draw the rotated line
g.draw(at.createTransformedShape(line));
}
好的,你需要计算线的长度,假设线的两端是(x0,y0)和(x1,y1),(x,y)是鼠标坐标,什么你想要的是在 (x0,y0) 和 (x,y) 之间的线上的点 (x2,y2),(x0,y0) 和 (x2,y2) 之间的距离必须与 ( x0,y0) 和 (x1,y1).
(x0,y0) 和 (x1,y1) 之间的距离是:
double dx = x1-x0;
double dy = y1-y0;
double length = Math.sqrt(dx*dx, dy*dy);
(x0,y0) 和 (x,y) 之间的距离是:
double dx1 = x-x0;
double dy1 = y-y0;
double mouseDist = Math.sqrt(dx1*dx1, dy1*dy1);
和 (x2,y2) 是:
int x2 = x0 + (int)(dx1*length/mouseDist);
int y2 = y0 + (int)(dy1*length/mouseDist);
static Point rotateLineClockWise(Point center, Point edge, int angle) {
double xRot = (int) center.x + Math.cos(Math.toRadians(angle)) * (edge.x - center.x) - Math.sin(Math.toRadians(angle)) * (edge.y - center.y);
double yRot = (int) center.y + Math.sin(Math.toRadians(angle)) * (edge.x - center.x) + Math.cos(Math.toRadians(angle)) * (edge.y - center.y);
return new Point((int) xRot, (int) yRot);
}
我用 Graphics 对象绘制了一条线。我想根据拖动鼠标的程度将这条线旋转一定的度数。我可以获得我需要旋转它的度数,但是我如何根据它旋转线?
谢谢!
我想您是在谈论 Java AWT 图形 class。图形可以认为是canvas。它是一个像素值数组,"drawing a line" 只是一个效用函数,它会更改其中一些像素的值 - 从它的角度来看,没有 "line object" 可言。通常你应该擦掉整个东西并用你想要的角度画一条新线。但是为此,您可能需要查看 Graphics2D (http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics2D.html),尤其是 setTransform 和 AffineTransform class.
您可以创建一个 Line2D
object for your original line. Then you can use AffineTransform#getRotateInstance
以获得一个 AffineTransform
,它围绕特定点旋转特定角度。使用此 AffineTransform
,您可以创建一个旋转的 Line2D
对象进行绘制。所以你的绘画代码大概是这样的:
protected void paintComponent(Graphics gr) {
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
// Create the original line, starting at the origin,
// and extending along the x-axis
Line2D line = new Line2D.Double(0,0,100,0);
// Obtain an AffineTransform that describes a rotation
// about a certain angle (given in radians!), around
// the start point of the line. (Here, this is the
// origin, so this could be simplified. But in this
// form, it's more generic)
AffineTransform at =
AffineTransform.getRotateInstance(
Math.toRadians(angleInDegrees), line.getX1(), line.getY1());
// Draw the rotated line
g.draw(at.createTransformedShape(line));
}
好的,你需要计算线的长度,假设线的两端是(x0,y0)和(x1,y1),(x,y)是鼠标坐标,什么你想要的是在 (x0,y0) 和 (x,y) 之间的线上的点 (x2,y2),(x0,y0) 和 (x2,y2) 之间的距离必须与 ( x0,y0) 和 (x1,y1).
(x0,y0) 和 (x1,y1) 之间的距离是:
double dx = x1-x0;
double dy = y1-y0;
double length = Math.sqrt(dx*dx, dy*dy);
(x0,y0) 和 (x,y) 之间的距离是:
double dx1 = x-x0;
double dy1 = y-y0;
double mouseDist = Math.sqrt(dx1*dx1, dy1*dy1);
和 (x2,y2) 是:
int x2 = x0 + (int)(dx1*length/mouseDist);
int y2 = y0 + (int)(dy1*length/mouseDist);
static Point rotateLineClockWise(Point center, Point edge, int angle) {
double xRot = (int) center.x + Math.cos(Math.toRadians(angle)) * (edge.x - center.x) - Math.sin(Math.toRadians(angle)) * (edge.y - center.y);
double yRot = (int) center.y + Math.sin(Math.toRadians(angle)) * (edge.x - center.x) + Math.cos(Math.toRadians(angle)) * (edge.y - center.y);
return new Point((int) xRot, (int) yRot);
}