说我有一个bool [] [],我想将它旋转37度。我知道转型并不总是完美的,那没关系。我已经准备好了很多类似于我的问题的答案,但我发现的唯一解决方案只能解决90度增量的问题。
答案 0 :(得分:6)
最好的方法是遍历目标位置,并为每个位置读取正确的源位置。如果你尝试相反的方式(即在源上循环并在目的地上书写),你最终会有差距。
旋转公式很简单......
source_x = dest_x * c + dest_y * s + x0
source_y = dest_x * -s + dest_y * c + y0
其中c
是角度的余弦值,s
是角度的正弦值,x0, y0
用于正确平移旋转的图像。在psedudocode
for y = 0, 1, ... dest_height
for x = 0, 1, ... dest_width
src_x = c*x + s*y + x0
src_y = -s*x + c*y + y0
copy from source[src_y][src_x] to dest[y][x]
可以计算 x0, y0
,以便源中心通过
x0 = src_width/2 - c*dest_width/2 - s*dest_height/2
y0 = src_height/2 - c*dest_height/2 + s*dest_width/2
如果不是仅使用c = cos(angle)
和s = sin(angle)
,而是使用因子k
缩放它们,则生成的图像将在中心周围旋转和缩放。
另请注意,公式在x
和y
中是双线性的;这意味着您可以使用完整公式获取行的第一个像素的完整值,然后对同一行的每个元素执行src_x += c
和src_y -= s
,因为这是从移动时发生的情况x
至x+1
。
另请注意,根据源和目标大小,计算的源元素可能不可用,因为图像外。在这种情况下,有几个常用的选项
false
)答案 1 :(得分:4)
其中x,y是笛卡尔坐标,R是旋转角度:
newx = x * cos(R) - y * sin(R)
newy = x * sin(R) + y * cos(R)
答案 2 :(得分:1)
假设您正在旋转位图,我首先考虑使用成像框架(例如System.Drawing)来实现您想要的效果。说,拿你的bool,把它变成一个1-bpp的位图,把它旋转,然后把它读出来。
如果那不是您想要的,您可以使用wberry提供的旋转并应用于每个bool,或者如果性能非常高,请编写自己的纹理化矩形光栅化器。要做到后者,请查看一些关于如何纹理映射任意2D多边形的旧图形编程教科书。
答案 3 :(得分:0)
除非你真的想要自己这样做,否则请考虑使用类似AForge的内容 - 更具体地说AForge.Imaging.Filters.RotateBicubic。此例程处理24bpp和8bpp图像,因此您需要将Alpha内容(作为24bpp图像)与Alpha通道分开旋转(作为8bpp图像)。