Java: 三角形旋转 - 不成功的概念
Java: Triangle rotation - unsuccessful concept
我做错了什么?我得到不正确的结果(坐标)。
一个三角形(见下图:蓝色为原三角形,石灰为旋转后的三角形:克隆。边A为固定点)。
我使用的classes:
一个点class:
public class Point {
private final double x;
private final double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
@Override
public String toString() {
return "[(" + x + ") (" + y + ")]";
}
}
一个抽象的 Object2D class:
public abstract class Object2D {
Point[] point;
public Point getPoint(int i) {
return point[i];
}
public double getLowestX() {
return Arrays.asList(point).stream()
.mapToDouble(Point::getX)
.min().getAsDouble();
}
public double getHighestX() {
return Arrays.asList(point).stream()
.mapToDouble(Point::getX)
.max().getAsDouble();
}
public double getLowestY() {
return Arrays.asList(point).stream()
.mapToDouble(Point::getY)
.min().getAsDouble();
}
public double getHighestY() {
return Arrays.asList(point).stream()
.mapToDouble(Point::getY)
.max().getAsDouble();
}
public double getLength() {
return getSide(getLowestX(), getHighestX());
}
public double getHeight() {
return getSide(getLowestY(), getHighestY());
}
private double getSide(double v1, double v2) {
return (v1 < v2) ? (0 - v1) + v2 : (0 - v2) + v1;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (Point pt : point) sb.append(pt).append("\n");
return sb.toString();
}
}
一行class:
public class Line extends Object2D {
public Line(Point point0, Point point1) {
point = new Point[2];
point[0] = point0;
point[1] = point1;
}
public double getLineLength() {
return Math.sqrt(Math.pow(getLength(), 2) + Math.pow(getHeight(), 2));
}
}
我的三角形class:
public class Triangle extends Object2D {
public Triangle(Point point0, Point point1, Point point2) {
point = new Point[3];
point[0] = point0;
point[1] = point1;
point[2] = point2;
}
public static Triangle getRotatedTriangle(Triangle triangle) {
Point point0 = triangle.getPoint(0);
Point point1 = triangle.getPoint(1);
Point point2 = triangle.getPoint(2);
Line baseLine = new Line(point0, point1);
double rotationHeight = baseLine.getHeight();
double baseLength = baseLine.getLineLength();
double sinA = rotationHeight / baseLength;
double angle = Math.asin(sinA);
double cosA = Math.cos(angle);
point1 = new Point(
(point1.getX() * cosA - point1.getY() * sinA),
(point1.getX() * sinA + point1.getY() * cosA));
point2 = new Point(
(point2.getX() * cosA - point2.getY() * sinA),
(point2.getX() * sinA + point2.getY() * cosA));
return new Triangle(point0, point1, point2);
}
}
当然还有我的主要 class:
public class TestDrive {
public static void main(String[] args) {
Triangle triangle = new Triangle (
new Point(-6.5, -1.5),
new Point(2.5, 7.5),
new Point(6.5, -5.5)
);
System.out.println(triangle);
System.out.println(Triangle.getRotatedTriangle(triangle));
}
}
您在代码中犯了 2 个错误:
- 您尝试以角度 α 旋转,而您应该以角度 -α 旋转(因为您是顺时针旋转)。
- 您的乘法矩阵不正确:您的代码将围绕 XY 平面的原点执行旋转,而不是围绕点 A 旋转。对于由旋转矩阵
R
旋转的点 (x, y)
围绕中心 (a, b)
,新旋转点 (x', y')
的正确公式将是 (x', y') = R * (x - a, y - b) + (a, b)
.
这应该足以让您更正代码。作为参考,这是我为旋转三角形得到的解决方案:
[(-6.5) (-1.5)]
[(6.227922061357855) (-1.5000000000000009)]
[(-0.1360389693210724) (-13.520815280171309)]
我做错了什么?我得到不正确的结果(坐标)。
一个三角形(见下图:蓝色为原三角形,石灰为旋转后的三角形:克隆。边A为固定点)。
一个点class:
public class Point {
private final double x;
private final double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
@Override
public String toString() {
return "[(" + x + ") (" + y + ")]";
}
}
一个抽象的 Object2D class:
public abstract class Object2D {
Point[] point;
public Point getPoint(int i) {
return point[i];
}
public double getLowestX() {
return Arrays.asList(point).stream()
.mapToDouble(Point::getX)
.min().getAsDouble();
}
public double getHighestX() {
return Arrays.asList(point).stream()
.mapToDouble(Point::getX)
.max().getAsDouble();
}
public double getLowestY() {
return Arrays.asList(point).stream()
.mapToDouble(Point::getY)
.min().getAsDouble();
}
public double getHighestY() {
return Arrays.asList(point).stream()
.mapToDouble(Point::getY)
.max().getAsDouble();
}
public double getLength() {
return getSide(getLowestX(), getHighestX());
}
public double getHeight() {
return getSide(getLowestY(), getHighestY());
}
private double getSide(double v1, double v2) {
return (v1 < v2) ? (0 - v1) + v2 : (0 - v2) + v1;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (Point pt : point) sb.append(pt).append("\n");
return sb.toString();
}
}
一行class:
public class Line extends Object2D {
public Line(Point point0, Point point1) {
point = new Point[2];
point[0] = point0;
point[1] = point1;
}
public double getLineLength() {
return Math.sqrt(Math.pow(getLength(), 2) + Math.pow(getHeight(), 2));
}
}
我的三角形class:
public class Triangle extends Object2D {
public Triangle(Point point0, Point point1, Point point2) {
point = new Point[3];
point[0] = point0;
point[1] = point1;
point[2] = point2;
}
public static Triangle getRotatedTriangle(Triangle triangle) {
Point point0 = triangle.getPoint(0);
Point point1 = triangle.getPoint(1);
Point point2 = triangle.getPoint(2);
Line baseLine = new Line(point0, point1);
double rotationHeight = baseLine.getHeight();
double baseLength = baseLine.getLineLength();
double sinA = rotationHeight / baseLength;
double angle = Math.asin(sinA);
double cosA = Math.cos(angle);
point1 = new Point(
(point1.getX() * cosA - point1.getY() * sinA),
(point1.getX() * sinA + point1.getY() * cosA));
point2 = new Point(
(point2.getX() * cosA - point2.getY() * sinA),
(point2.getX() * sinA + point2.getY() * cosA));
return new Triangle(point0, point1, point2);
}
}
当然还有我的主要 class:
public class TestDrive {
public static void main(String[] args) {
Triangle triangle = new Triangle (
new Point(-6.5, -1.5),
new Point(2.5, 7.5),
new Point(6.5, -5.5)
);
System.out.println(triangle);
System.out.println(Triangle.getRotatedTriangle(triangle));
}
}
您在代码中犯了 2 个错误:
- 您尝试以角度 α 旋转,而您应该以角度 -α 旋转(因为您是顺时针旋转)。
- 您的乘法矩阵不正确:您的代码将围绕 XY 平面的原点执行旋转,而不是围绕点 A 旋转。对于由旋转矩阵
R
旋转的点(x, y)
围绕中心(a, b)
,新旋转点(x', y')
的正确公式将是(x', y') = R * (x - a, y - b) + (a, b)
.
这应该足以让您更正代码。作为参考,这是我为旋转三角形得到的解决方案:
[(-6.5) (-1.5)]
[(6.227922061357855) (-1.5000000000000009)]
[(-0.1360389693210724) (-13.520815280171309)]