I'm trying to rotate a Bitmap where the pixels are stored in an Array int pixels[]
. I got the following method:
public void rotate(double angle) {
double radians = Math.toRadians(angle);
double cos, sin;
cos = Math.cos(radians);
sin = Math.sin(radians);
int[] pixels2 = pixels;
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++) {
int centerx = this.width / 2, centery = this.height / 2;
int m = x - centerx;
int n = y - centery;
int j = (int) (m * cos + n * sin);
int k = (int) (n * cos - m * sin);
j += centerx;
k += centery;
if (!((j < 0) || (j > this.width - 1) || (k < 0) || (k > this.height - 1)))
try {
pixels2[(x * this.width + y)] = pixels[(k * this.width + j)];
} catch (Exception e) {
e.printStackTrace();
}
}
pixels = pixels2;
}
But it just gives me crazy results. Does anyone know where the error is?
The line
int[] pixels2 = pixels;
is supposed to copy the array, but you are just copying the reference to it. Use pixels.clone()
. In fact, you just need a new, empty array, so new int[pixels.lenght]
is enough. In the end you need System.arraycopy
to copy the new content into the old array.
There are other problems in your code -- you are mixing up rows and columns. Some expressions are written as though the image is stored row by row, others as if column by column. If row-by-row (my assumption), then this doesn't make sense: x*width + y
. It should read y*width + x
-- you are skipping y
rows down and then moving x
columns to the right. All in all, I have this code that works OK:
import static java.lang.System.arraycopy;
public class Test
{
private final int width = 5, height = 5;
private int[] pixels = {0,0,1,0,0,
0,0,1,0,0,
0,0,1,0,0,
0,0,1,0,0,
0,0,1,0,0};
public Test rotate(double angle) {
final double radians = Math.toRadians(angle),
cos = Math.cos(radians), sin = Math.sin(radians);
final int[] pixels2 = new int[pixels.length];
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++) {
final int
centerx = this.width / 2, centery = this.height / 2,
m = x - centerx,
n = y - centery,
j = ((int) (m * cos + n * sin)) + centerx,
k = ((int) (n * cos - m * sin)) + centery;
if (j >= 0 && j < width && k >= 0 && k < this.height)
pixels2[(y * width + x)] = pixels[(k * width + j)];
}
arraycopy(pixels2, 0, pixels, 0, pixels.length);
return this;
}
public Test print() {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++)
System.out.print(pixels[width*y + x]);
System.out.println();
}
System.out.println();
return this;
}
public static void main(String[] args) {
new Test().print().rotate(-45).print();
}
}
public void render(float nx, float ny, float nz, float size, float rotate) {
int wid = (int) ((width - nz) * size);
int hgt = (int) ((height - nz) * size);
if (wid < 0 || hgt < 0) {
wid = 0;
hgt = 0;
}
for (int x = 0; x < wid; x++) {
for (int y = 0; y < hgt; y++) {
double simple = Math.PI;
int xp = (int) (nx +
Math.cos(rotate) * ((x / simple) - (wid / simple) / 2) + Math
.cos(rotate + Math.PI / 2)
* ((y / simple) - (hgt / simple) / 2));
int yp = (int) (ny + Math.sin(rotate)
* ((x / simple) - (wid / simple) / 2) + Math.sin(rotate
+ Math.PI / 2)
* ((y / simple) - (hgt / simple) / 2));
if (xp + width < 0 || yp + height < 0 || xp >= Main.width
|| yp >= Main.height) {
break;
}
if (xp < 0
|| yp < 0
|| pixels[(width / wid) * x + ((height / hgt) * y)
* width] == 0xFFFF00DC) {
continue;
}
Main.pixels[xp + yp * Main.width] = pixels[(width / wid) * x
+ ((height / hgt) * y) * width];
}
}
}
This is only a new to rotating for me, but the process of this is that of a normal rotation. It still needs much fixing -- it's inefficient and slow. But in a small program, this code works. I'm posting this so you can take it, and make it better. :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.