2010-01-03 2 views
4

Я пишу программу для рисования, 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, он может быть применим к любому языку

ответ

6

Я предполагаю, что resize() вызывается для каждого обновления движения мыши. Ваша проблема, кажется, self.angle += 1, что заставляет вас обновлять свой угол на 1 градус при каждом событии мыши.

Решение проблемы: выберите точку на изображении, где вращение будет центрировано (на этом случае это (0,0) точка на self.img.Rotate(), но обычно это центр изображения). Угол поворота должен быть углом, образованным линией, идущей от этой точки до курсора мыши, минус угол, образованный линией, идущей от этой точки до положения мыши, когда пользователь щелкнул.

Чтобы вычислить угол между двумя точками, используйте math.atan2(y2-y1, x2-x1), который даст вам угол в радианах. (вам может потребоваться изменить порядок вычитаний в зависимости от оси положения мыши). Решение

+0

Спасибо, я пойду попробовать.Я просто использовал 1 для угла, потому что я действительно не знал, как подойти к проблеме. Хороший улов (0, 0) тоже, я забыл рассчитать центр изображения и продолжал вращать его вокруг верхнего левого изображения. Спасибо. –

1

fserb является то, как я бы идти о ротации тоже, но что-то дополнительное, чтобы рассмотреть ваше использование:

img = self.img.Rotate(rad, (0, 0)) 

Если вы выполняете поворот растрового изображения в ответ на каждое событие мыши перетащить, вы получите большую потерю данных из совокупного эффекта всей интерполяции, необходимой для вращения. Например, вращение на 1 градус 360 раз даст вам гораздо более грубое изображение, чем оригинал.

Попробуйте имея систему вращения что-то вроде этого:

display_img = self.img.Rotate(rad, pos) 

затем использовать display_img изображение, пока вы находитесь в режиме вращения. Когда вы закончите режим вращения (onMouseUp возможно), img = display_img.

Этот тип стратегии хорош, когда у вас есть операция с потерей при предварительном просмотре пользователя.

+0

Спасибо, это хорошая идея. Я буду преобразовывать в использование прозрачного многоугольника и вращать его, когда пользователь перемещает мышь, а затем выполняет поворот только тогда, когда они отпускают кнопку мыши - это слишком высокая производительность, чтобы отображать изображение при его повороте. –

+0

Вы также можете отображение версии с низким разрешением изображения повернуто, в зависимости от производительности. – tkerwin

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 
Смежные вопросы