Rotating a 2D pixel array by 90 degrees
This can be done without using any extra space, so called In-place matrix transposition (not exact the same). Remember to do some mirroring after the transposition.
If the image is square
If the image is not square
- For non-square matrices, the algorithms are more complicated. Many of the algorithms prior to 1980 could be described as "follow-the-cycles" algorithms. That is, they loop over the cycles, moving the data from one location to the next in the cycle. In pseudocode form:
C - Rotate a image by 90 degree (right and left) using one array - bitmap
You can use the rotation matrix
.
The rotation matrix for 90 degrees is simply
[0 -1
1 0]
here you can see how to do matrix multiplication in c if you need.
How do you rotate a two dimensional array?
Here it is in C#
int[,] array = new int[4,4] {
{ 1,2,3,4 },
{ 5,6,7,8 },
{ 9,0,1,2 },
{ 3,4,5,6 }
};
int[,] rotated = RotateMatrix(array, 4);
static int[,] RotateMatrix(int[,] matrix, int n) {
int[,] ret = new int[n, n];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
ret[i, j] = matrix[n - j - 1, i];
}
}
return ret;
}
Algorithm to rotate an image 90 degrees in place? (No extra memory)
This might help: In-place matrix transposition.
(You might also have to do some mirroring after the transposition, as rlbond mentions).
Rotating a bitmap and transform the resulting coordinates in float format back to integer x,y values for pixel array
What if you invert the rotation and calculate backwards
new_x, new_x -> old_x, old_y
That would resolve the rounding errors.
for new_pixel_coordinates:
old_pixel_coordinates = inverse_rotate(new_pixel_coordinates)
color = lookup_color(old_bitmap, old_pixel_coordinates)
color_new_picture(new_bitmap, new_pixel_coordinates, color)
python rotate image by 90 degrees without using any libs
You can rotate a grid of pixels by 90° by a combination of transposition and reflection. You can do this in pure Python by using zip
to transpose, and reversed
to reflect.
Here's a short demo that does a 90° clockwise rotation.
# Some fake pixels
data = [
[(100, 101, 102), (105, 106, 107), (110, 111, 112), (115, 116, 117)],
[(120, 121, 122), (125, 126, 127), (130, 131, 132), (135, 136, 137)],
[(140, 141, 142), (145, 146, 147), (150, 151, 152), (155, 156, 157)],
[(160, 161, 162), (165, 166, 167), (170, 171, 172), (175, 176, 177)],
[(180, 181, 182), (185, 186, 187), (190, 191, 192), (195, 196, 197)],
]
new = [list(reversed(t)) for t in zip(*data)]
for row in new:
print(row)
output
[(180, 181, 182), (160, 161, 162), (140, 141, 142), (120, 121, 122), (100, 101, 102)]
[(185, 186, 187), (165, 166, 167), (145, 146, 147), (125, 126, 127), (105, 106, 107)]
[(190, 191, 192), (170, 171, 172), (150, 151, 152), (130, 131, 132), (110, 111, 112)]
[(195, 196, 197), (175, 176, 177), (155, 156, 157), (135, 136, 137), (115, 116, 117)]
But seriously, it's faster (and simpler) to do this sort of thing with a library, unless the images are really small. If you don't want to use PIL, you can do it with Numpy.
How can I rotate a 2d array by LESS than 90°, to the best approximation?
Ok here it is as promised. First C++ code:
//---------------------------------------------------------------------------
#include <math.h>
//---------------------------------------------------------------------------
const int xs=7; // matrix size
const int ys=7;
const int x0=3; // rotation center cell
const int y0=3;
const float deg=M_PI/180.0;
int A[xs][ys]=
{
{0,0,0,9,0,0,0},
{0,0,0,9,0,0,0},
{0,0,0,9,0,0,0},
{9,9,9,9,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
};
int B[xs][ys];
//---------------------------------------------------------------------------
void rotcw(int x0,int y0,float ang) // rotate A -> B by angle ang around (x0,y0) CW if ang>0
{
int x,y,ix0,iy0,ix1,iy1,q;
float xx,yy,fx,fy,c,s;
// circle kernel
c=cos(-ang); s=sin(-ang);
// rotate
for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
{
// offset so (0,0) is center of rotation
xx=x-x0;
yy=y-y0;
// rotate (fx,fy) by ang
fx=float((xx*c)-(yy*s));
fy=float((xx*s)+(yy*c));
// offset back and convert to ints and weights
fx+=x0; ix0=floor(fx); fx-=ix0; ix1=ix0+1; if (ix1>=xs) ix1=ix0;
fy+=y0; iy0=floor(fy); fy-=iy0; iy1=iy0+1; if (iy1>=ys) iy1=iy0;
// bilinear interpolation A[ix0+fx][iy0+fy] -> B[x][y]
if ((ix0>=0)&&(ix0<xs)&&(iy0>=0)&&(iy0<ys))
{
xx=float(A[ix0][iy0])+(float(A[ix1][iy0]-A[ix0][iy0])*fx);
yy=float(A[ix0][iy0])+(float(A[ix1][iy0]-A[ix0][iy0])*fx);
xx=xx+((yy-xx)*fy); q=xx;
} else q=0;
B[x][y]=q;
}
}
//---------------------------------------------------------------------------
Here 7x7 preview 15 deg steps:
It may be need a bit tweaking of the center by half of cell or something (the center is bleeding too much to my liking)
Matrix A
is source and B
is target ...
You can also add tresholding ... like:
if (q>=5) q=9; else q=0;
Related Topics
Modifying Reference Member from Const Member Function in C++
Can a Lambda Capturing Nothing Access Global Variables
How to Create a Temporary Text File in C++
Does the Evil Cast Get Trumped by the Evil Compiler
How to Pass a Part of a Vector as a Function Argument
How to Get Content of Web-Page
Array Overflow (Why Does This Work)
Why Uninitialized Global Variable Is Weak Symbol
How to Find How Much Memory Is Shared Between Forked Process with Copy-On-Write in Linux
How to Check If a File Is Still Being Written
Should Function Declarations Include Parameter Names
Using Boost::Iostreams::Tee_Device
What Is a Cross-Platform Way to Get the Current Directory
Undefined Symbols in Crypto++/iOS 64-Bit Project
Compiling Simple Static Opengl 4.0 Program Using Mingw, Freeglut and Glew
How to Find The Full Path of The C++ Linux Program from Within