我正在写一个绘图程序,Whyteboard - http://code.google.com/p/whyteboard/
我已经实现了图像旋转功能,除了它的行为有点奇怪。我无法弄清楚使图像相对于鼠标位置旋转的正确逻辑
我的代码与此类似:
(这些是从鼠标事件处理程序调用的)
def resize(self, x, y, direction=None):
"""Rotate the image"""
self.angle += 1
if self.angle > 360:
self.angle = 0
self.rotate()
def rotate(self, angle=None):
"""Rotate the image (in radians), turn it back into a bitmap"""
rad = (2 * math.pi * self.angle) / 360
if angle:
rad = (2 * math.pi * angle) / 360
img = self.img.Rotate(rad, (0, 0))
因此,当用户移动鼠标时,基本上旋转图像的角度会不断增加。但是,这有时意味着您必须多次“圈”鼠标才能将图像旋转90度,更不用说360度了。
但是,我需要它与其他程序类似 - 图像如何相对于鼠标在图像上的位置旋转。
这是我遇到麻烦的一点。我已经离开了与语言无关的问题,尽管使用Python和wxPython它可以适用于任何语言
答案 0 :(得分:6)
我假设每次鼠标移动更新都会调用resize()
。您的问题似乎是self.angle += 1
,这会让您在每次鼠标事件时将角度更新1度。
问题的解决方案是:选择图像中旋转将居中的点(在这种情况下,它是(0,0)
上的self.img.Rotate()
点,但通常它是图片)。旋转角度应该是从该点到鼠标光标的线形成的角度减去用户点击时从该点到鼠标位置的线形成的角度。
要计算两点之间的角度,请使用math.atan2(y2-y1, x2-x1)
,它将以弧度为单位给出角度。 (您可能需要根据鼠标位置轴更改减法的顺序。)
答案 1 :(得分:1)
fserb的解决方案也是我对旋转方式的解决方法,但您可以考虑使用以下内容:
img = self.img.Rotate(rad, (0, 0))
如果您正在执行位图图像旋转以响应每个鼠标拖动事件,那么您将从旋转所需的所有插值的组合效果中获得大量数据丢失。例如,旋转1度360度将使您的图像比原始图像更加模糊。
尝试使用这样的旋转系统:
display_img = self.img.Rotate(rad, pos)
然后在旋转模式下使用display_img
图像。当你结束轮换模式时(onMouseUp
可能),img = display_img
。
只要您通过用户预览进行有损操作,此类策略就会很好。
答案 2 :(得分:0)
这是最终的解决方案,
def rotate(self, position, origin):
""" position: mouse x/y position, origin: x/y to rotate around"""
origin_angle = self.find_angle(origin, self.center)
mouse_angle = self.find_angle(position, self.center)
angle = mouse_angle - origin_angle
# do the rotation here
def find_angle(self, a, b):
try:
answer = math.atan2((a[0] - b[0]) , (a[1] - b[1]))
except:
answer = 0
return answer