用鼠标旋转图像
我正在编写一个绘图程序 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 它可以适用于任何语言
I am writing a drawing program, Whyteboard -- http://code.google.com/p/whyteboard/
I have implemented image rotating functionality, except that its behaviour is a little odd. I can't figure out the proper logic to make rotating the image in relation to the mouse position
My code is something similar to this:
(these are called from a mouse event handler)
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))
So, basically the angle to rotate the image keeps getting increased when the user moves the mouse. However, this sometimes means you have to "circle" the mouse many times to rotate an image 90 degrees, let alone 360.
But, I need it similar to other programs - how the image is rotated in relation to your mouse's position to the image.
This is the bit I'm having trouble with. I've left the question language-independent, although using Python and wxPython it could be applicable to any language
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我假设每次鼠标移动更新都会调用
resize()
。您的问题似乎是self.angle += 1
,它使您在每次鼠标事件时将角度更新 1 度。解决您的问题的方法是:选择图像上旋转中心的点(在本例中,它是
self.img.Rotate( 上的
,但通常它是图像的中心)。旋转角度应该是从该点到鼠标光标的连线所形成的角度减去用户单击时从该点到鼠标位置的连线所形成的角度。(0,0)
点) )要计算两点之间的角度,请使用math.atan2(y2-y1, x2-x1),它会给出以弧度为单位的角度。 (您可能需要根据鼠标位置轴更改减法的顺序)。
I'm assuming
resize()
is called for every mouse movement update. Your problem seems to be theself.angle += 1
, which makes you update your angle by 1 degree on each mouse event.A solution to your problem would be: pick the point on the image where the rotation will be centered (on this case, it's your
(0,0)
point onself.img.Rotate()
, but usually it is the center of the image). The rotation angle should be the angle formed by the line that goes from this point to the mouse cursor minus the angle formed by the line that goes from this point to the mouse position when the user clicked.To calculate the angle between two points, use
math.atan2(y2-y1, x2-x1)
which will give you the angle in radians. (you may have to change the order of the subtractions depending on your mouse position axis).fserb 的解决方案也是我进行旋转的方式,但需要额外考虑的是您的使用:
如果您正在执行位图图像旋转以响应每个鼠标拖动事件,您将会丢失大量数据旋转所需的所有插值的综合效果。例如,旋转 1 度 360 次会得到比原始图像模糊得多的图像。
尝试使用类似这样的旋转系统:
然后在旋转模式下使用
display_img
图像。当您结束旋转模式时(可能是onMouseUp
),img = display_img
。每当您对用户预览进行有损操作时,这种类型的策略就很好。
fserb's solution is the way I would go about the rotation too, but something additional to consider is your use of:
If you are performing a bitmap image rotation in response to every mouse drag event, you are going to get a lot of data loss from the combined effect of all the interpolation required for the rotation. For example, rotating by 1 degree 360 times will give you a much blurrier image than the original.
Try having a rotation system something like this:
then use the
display_img
image while you are in rotation mode. When you end rotation mode (onMouseUp
maybe),img = display_img
.This type of strategy is good whenever you have a lossy operation with a user preview.
最后的解决方案是这样的
Here's the solution in the end,