我开始为游戏开发一个自定义Image类,它包含三个基本字段,宽度,高度和一维的int的一维数组,它们按以下顺序表示颜色。
大约两天前我开始尝试旋转图像,我能够通过将其转换为BufferedImage,使用Graphics2D旋转并将其转换回我自己的Image类来实现,但是setRGB和getRGB似乎太慢了当我必须旋转大约10-20个64 * 64像素的图像时,计算机开始努力维持fps。
很自然地,我开始开发自己的图像旋转功能,我在gamedev.stackexchange上发现了一篇很棒的帖子。
https://gamedev.stackexchange.com/questions/67613/how-can-i-rotate-a-bitmap-without-d3d-or-opengl
答案清楚地解释了即使使用不同的旋转点(我打算稍后实施)也应该如何旋转图像。
然而,当遵循他解释的那个类似的公式时(由于使用不同的坐标系我不得不改变) 我发现自己在顶部得到一个奇怪的包装
示例(55度):http://i.imgur.com/BBq83wV.png(黑色区域代表图像大小)
所以我试图从顶部分散图像,然后添加
yDstPixel += this.height*sin;
哪种方法有效,但现在图像被剪切了一半而不是包裹
示例(35度):http://i.imgur.com/Ap4aqrn.png
我几乎可以肯定解决方案非常简单,但我似乎无法弄清楚,正确方向的推动将会受到赞赏。
public Bitmap getRotatedCopy(double radians){
if(radians==0 || radians==(2*Math.PI)) return this;
double sin = Math.abs(Math.sin(radians));
double cos = Math.abs(Math.cos(radians));
int newWidth = (int) (this.width * cos + this.height * sin);
int newHeight = (int) (this.width * sin + this.height * cos);
Bitmap returnMap = new Bitmap(newWidth,newHeight); //set size of the returned bitmap to the smallest size possible
returnMap.fill(0xFF000000);
for (int y = 0; y < this.height; y++){
for(int x = 0; x < this.width; x++){
int srcPixel = x + (y * this.width);
int color= this.pixels[srcPixel];
if(color>0) continue;
int xDstPixel = (int) Math.abs((x * cos + y * sin));
int yDstPixel = (int) Math.abs((x * sin - y * cos));
//yDstPixel += this.height*sin;
int dstPixel = xDstPixel + (yDstPixel * newWidth);
returnMap.pixels[dstPixel]=color;
}
}
return returnMap;
}
答案 0 :(得分:0)
您需要实施您计划稍后执行的操作,即在旋转后设置旋转原点和平移。
我修改了您的代码以添加它们。 (我没有测试运行它,但希望它有效。)请参考下面的代码:
int newWidth = (int) (this.width * cos + this.height * sin);
int newHeight = (int) (this.width * sin + this.height * cos);
// After setting the new width and height...
// set rotation origin
double rox = this.width/2;
double roy = this.height/2;
// set translation center
double tcx = newWidth/2;
double tcy = newHeight/2;
Bitmap returnMap = new Bitmap(newWidth,newHeight);
returnMap.fill(0xFF000000);
for (int y = 0; y < this.height; y++){
double yy = y - roy;
for(int x = 0; x < this.width; x++){
double xx = x - rox;
int srcPixel = x + (y * this.width);
int color= this.pixels[srcPixel];
if(color>0) continue;
// following two lines are modified
int xDstPixel = (int) (xx * cos + yy * sin) + tcx;
int yDstPixel = (int) (xx * sin - yy * cos) + tcy;
// prevent negative index : maybe it is not needed at all
if (xDstPixel<0 || yDstPixel<0)
continue;
int dstPixel = xDstPixel + (yDstPixel * newWidth);
returnMap.pixels[dstPixel]=color;
}
}