0

我正在使用这些文章 [ 1 ][ 2 ] 中记录的三剪切方法旋转位图。

从大约 0 到 90°,质量是可以接受的,但除此之外,它会逐渐失真,直到无法理解。 位图图像旋转

谁能帮我找出问题所在?应用程序 Cinema 4D 的 API 调用了一些方法,但我相信问题出在数学上。谢谢!

这是我的剪切函数:

def shear(angle,x,y):
    '''
    |1  -tan(/2) |  |1        0|  |1  -tan(/2) |
    |0      1     |  |sin()   1|  |0      1     |

    '''
    # shear 1
    tangent=math.tan(angle/2)
    new_x=round(x-y*tangent)
    new_y=y

    #shear 2
    new_y=round(new_x*math.sin(angle)+new_y)      #since there is no change in new_x according to the shear matrix

    #shear 3
    new_x=round(new_x-new_y*tangent)              #since there is no change in new_y according to the shear matrix

    return new_x,new_y

这是绘图函数中的代码:

cos = math.cos(self.rotation)
sin = math.sin(self.rotation)

# Define the width and height of the destination image
newWidth = round(abs(w*cos)+abs(h*sin))+1
newHeight = round(abs(h*cos)+abs(w*sin))+1

destBmp = c4d.bitmaps.BaseBitmap() #creates a new BaseBitmap instance for the destination image
destBmp.Init(newWidth,newHeight) #initializes the bitmap
destAlpha = destBmp.AddChannel(True, False) #adds an alpha channel

# Find the center of the source image for rotation
origCenterWidth  = round(((w+1)/2)-1)    #with respect to the source image
origCenterHeight = round(((h+1)/2)-1)    #with respect to the source image

# Find the center of the destination image
newCenterWidth  = round(((newWidth+1)/2)-1)  #with respect to the destination image
newCenterHeight = round(((newHeight)/2)-1)  #with respect to the destination image

for xP in range(w):
  for yP in range(h):
      destBmp.SetPixel(int(xP), int(yP), 0, 0, 255) #sets the destination bitmap's background color to blue

for i in range(h):
    for j in range(w):
        #co-ordinates of pixel with respect to the center of source image
        x = w-1-j-origCenterWidth
        y = h-1-i-origCenterHeight

        #Applying the Shear Transformation
        new_x,new_y = shear(self.rotation,x,y)

        #with rotation, the center will change so new_x and new_y will be the new center
        new_y = newCenterHeight-new_y
        new_x = newCenterWidth-new_x

        alphaValue = sourceBmp.GetAlphaPixel(alphaChannel, j, i) #gets the source image pixel's alpha
        col = sourceBmp.GetPixelDirect(j, i) #gets the source image pixel's color as a Color Vector
        destBmp.SetAlphaPixel(nBmpAlpha, int(new_x), int(new_y), alphaValue) #sets the destination image pixel's alpha
        destBmp.SetPixel(int(new_x), int(new_y), int(col.x), int(col.y), int(col.z)) #sets the destination image pixel's color
4

1 回答 1

0

I ran accross the same exact problem today. It seems as though there is something about the shearing method that is most optimal between 315 and 45 degrees, and noticeably degrades between 90 and 270. What I did to get around this was flip the image both on x, and y if the rotation is between 90 and 270, and then tack on an extra 180, to get it back into the desired range of rotation.

Here's basically what that was:

if (rotation > 90 && rotation < 270) {
    scale.x = scale.x * -1.0f;
    scale.y = scale.y * -1.0f;
    rotation += 180; 
    if (rotation >= 360) {
        rotation -= 360;
    }
}
于 2021-09-16T12:40:29.750 回答