【问题标题】:2D point rotation based off a matrix基于矩阵的二维点旋转
【发布时间】: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 等功能

标签: java math matrix rotation


【解决方案1】:

您已经使用方程来绕坐标原点 (0,0) 旋转。

如果你想围绕任意中心 (cx, cy) 旋转(我认为在你的情况下是矩阵的中间),那么方程是:

 x' = cx + (x-cx) * Cos(theta) - (y-cy) * Sin(theta)
 y' = cy + (x-cx) * Sin(theta) + (y-cy) * Cos(theta)

编辑:
还有另一种就地变换矩阵的方法:
给定:函数 F 将某个坐标 (x,y) 映射到新坐标 (x',y')
Find inverse function G=Inverse(F) 为给定目的地 (x',y') 找到源坐标 (x,y) 遍历矩阵坐标 i,j
提取Element[i,j]
查找i',j' = G(i,j)
复制 Element[i',j'] 到 i,j 坐标
重复 i'j' 直到返回 i,j(4 或 2 个循环)
将提取的Element[i,j] 复制到最终位置

示例:关于垂直轴的镜像

G(x,y) = (n-1-x, y)
extract R=A[0,0]
G(0,0) = n-1,0
copy A[n-1,0] to A[0,0] 
G(n-1,0) = 0,0        //start coordinate reached
copy R to A[n-1, 0]
do the same for all x<n/2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    • 2011-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多