【发布时间】:2016-08-02 10:18:17
【问题描述】:
我有一个 6x6 矩阵,关键点为 G,空点为连字符。 (O 和 L 与此问题无关。请注意,侧面和顶部的数字以及左上角的连字符仅用于标记轴。)
// Original Matrix
- 012345
0 ----G-
1 ----L-
2 ----L-
3 ----L-
4 GOOOL-
5 ------
通过以下两种方法,我可以将上面的矩阵向左旋转90度。
public static void transpose(int[][] m) {
for (int x = 0; x < m.length; x++) {
for (int y = x; y < m[0].length; y++) {
int temp = m[x][y];
m[x][y] = m[y][x];
m[y][x] = temp;
}
}
}
public static void swapRows(int[][] m) {
for (int i = 0, k = m.length - 1; i < k; ++i, --k) {
int[] x = m[i];
m[i] = m[k];
m[k] = x;
}
}
交换行,然后转置行,得到以下矩阵。 (以下解释包括180度旋转)
// Rotated -90° Matrix // Rotated 180° Matrix
- 012345 - 012345
0 ------ 0 ------
1 GLLLL- 1 -LOOOG
2 ----O- 2 -L----
3 ----O- 3 -O----
4 ----O- 4 -O----
5 ----G- 5 -G----
在代码中,我还有一个 java.awt.Point 的 ArrayList,用于存储 G 点的位置。矩阵旋转后,必须更新这些点。我可以扫描数组中的 G 点,尽管每个点必须在 ArrayList 中保持相同的索引,并且无论以何种方式扫描它,都不能保证原始矩阵中第一个点的索引将保留在与 90 度或 180 度矩阵中的第一个点相同的索引。
对于ArrayList的
public ArrayList<java.awt.Point> keyPoints = new ArrayList<>();
keyPoints.add(new Point(0, 4));
keyPoints.add(new Point(4, 0));
我目前有这种方法来旋转点。
它基于以下等式。
for (int i = 0; i < keyPoint.size(); i++) {
Point p = keyPoint.get(i);
double angle = Math.toRadians(-90);
double cos = Math.cos(angle);
double sin = Math.sin(angle);
double x = (p.x * cos) - (p.y * sin);
double y = (p.x * sin) + (p.y * cos);
keyPoint.set(i, new Point((int) x, (int) y));
System.out.printf("Point: (%.2f, %.2f)\n", x, y);
}
对于90度旋转,我目前得到的输出如下
Point: (4.00, 0.00)
Point: (0.00, -4.00)
虽然对于 90°,我正在寻找的输出是
Point: (0.00, 1.00)
Point: (4.00, 5.00)
您对我的 for 循环的实现有什么建议(如果不是更好的解决方案)?
【问题讨论】:
-
您要旋转 90*n 以外的角度吗?
-
所有旋转都是 90*n。由于我的矩阵设置,我不相信 90*n 之外的旋转是可能的。
-
所以你最好设置一些表用-1/0/1而不是sin/cos计算。
-
@MBo 这只会影响计算速度,还是有其他用途?
-
速度和清晰度(我希望)——您可以在代码中看到类似 Table90 的内容。看看我的答案编辑。该方法就地有效,并且可能使用 G90 等功能