Java 旋转位图时奇怪的包裹

Java 旋转位图时奇怪的包裹,java,matrix,rotation,transform,pixel,Java,Matrix,Rotation,Transform,Pixel,我开始为一个游戏开发一个自定义图像类,该类由三个基本字段组成:宽度、高度和一个一维int数组,int数组表示以下顺序ARGB的颜色 大约两天前,我开始尝试旋转图像,通过将其转换为BuffereImage,使用Graphics2D进行旋转,并将其转换回我自己的图像类,我能够做到这一点,然而,setRGB和getRGB似乎太慢了,当我必须旋转大约10-20张64*64像素的图像时,计算机开始努力维持fps 所以我很自然地开始开发自己的图像旋转功能,并在gamedev.stackexchange上找到

我开始为一个游戏开发一个自定义图像类,该类由三个基本字段组成:宽度、高度和一个一维int数组,int数组表示以下顺序ARGB的颜色

大约两天前,我开始尝试旋转图像,通过将其转换为BuffereImage,使用Graphics2D进行旋转,并将其转换回我自己的图像类,我能够做到这一点,然而,setRGB和getRGB似乎太慢了,当我必须旋转大约10-20张64*64像素的图像时,计算机开始努力维持fps

所以我很自然地开始开发自己的图像旋转功能,并在gamedev.stackexchange上找到了一篇很棒的帖子

答案清楚地解释了即使使用不同的旋转点,我也应该做些什么来旋转图像,我打算稍后实现这些旋转点

然而,当遵循一个与他解释的类似的公式时,由于使用了不同的坐标系,我不得不改变 我发现自己的顶部有一个奇怪的包装

示例55度:黑色区域表示图像大小

所以我试着将图像与顶部隔开,并添加

yDstPixel += this.height*sin;
这部分工作正常,但现在图像被剪成两半而不是包装

示例35度:

我几乎可以肯定这个解决方案是非常简单的,但我似乎无法理解,如果能朝着正确的方向轻推一下,我将不胜感激

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;
}

您将需要执行稍后计划执行的操作,即设置旋转原点和旋转后的平移

我已修改您的代码以添加它们。我没有测试运行它,但希望它能工作。请参考以下代码:

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;
    }
}

谢谢你,在我用你的代码在newWidth和newHeight中添加了一个之后,它工作了。