【问题标题】:Strange wraping when rotating Bitmaps旋转位图时奇怪的环绕
【发布时间】:2014-07-10 23:45:27
【问题描述】:

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

大约两天前,我开始尝试旋转图像,我能够通过将其转换为 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;
}

【问题讨论】:

    标签: java matrix rotation transform pixel


    【解决方案1】:

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

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

    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 中添加了一个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多