就地旋转2D矩形阵列

时间:2010-09-23 09:56:13

标签: c++ arrays rotation in-place

我有一个像这样的非方阵:

const int dim1 = 3, dim2 = 4;
int array[12] = { 1, 2, 3, 
                  4, 5, 6,
                  7, 8, 9,
                 10,11,12};

我需要将其转换为:

{3,6,9,12,
 2,5,8,11,
 1,4,7,10}

即逆时针旋转/旋转(或顺时针旋转,算法应该类似)。

该算法应使用最小量的空间。我必须在极其受内存限制的环境中旋转图像,因此空间越小越好。速度不是一个大问题。

4 个答案:

答案 0 :(得分:7)

您可以就地转置矩阵(请参阅http://en.wikipedia.org/wiki/In-place_matrix_transposition),然后将这些行转换为无关紧要的行。

答案 1 :(得分:1)

2D旋转公式为:

x' = x cos f - y sin f
y' = y cos f + x sin f

如果仅以90°步进旋转,则生成的公式变为:

x' = -y
y' =  x

由于数组不是正方形,你必须寻找赋值循环,即元素(0,0)被赋予赋值元素(2,0),而元素(2,0)又被赋值(2,2)等等。你将会需要在“相同”的时间分配每个周期。

因此,为了旋转整个数组,您将执行类似(伪代码)的操作:

// this function rotates 90 degrees
point successor(const point &p)
{
  return (-p.y, p.x);
}

// this function rotates 90 degrees in opposite direction
point predecessor(const point &p)
{
  return (p.y, -p.x);
}

void replace_cycle(const point &start)
{
  int data = get_data(start);
  point x = predecessor(start);
  while(x != start)
  {
    set_data(successor(x), get_data(x));
    x = predecessor(x);
  }
  set_data(successor(start), data);
}

void rotate_in_place()
{
  list<point> l;
  find_cycles(l);
  foreach(c in l)
  {
    replace_cycle(c);
  }
}

答案 2 :(得分:0)

根本不旋转可能是一种选择。您只需设置一个标志,该标志将指示矩阵应该被读取的方式。

缺点是如果必须将图像提供给某些显示设备或具有固定方向的显示设备,则可能无法实现。

答案 3 :(得分:-1)

您可以使用xor使用附加内存。

// Switch a and b
int a;
int b;
a ^= b;
b ^= a;
a ^= b;

然后你可以使用一个简单的for循环来制作整个矩阵。