Вопрос

У меня есть NSImage, нарисованный в подклассе NSView.В предыдущем вопросе мне помогли нарисовать его вертикально в левом верхнем углу.Теперь я хочу иметь возможность вращать изображение.У меня есть кнопка, которая увеличивает переменную поворота %4, а затем я умножаю ее на -90, чтобы найти угол поворота.Затем я использую NSAffineTransform, чтобы повернуть изображение и перевести его обратно на экран.Однако, похоже, это работает не так, как я ожидаю.У меня есть две проблемы.

1) При повороте часть изображения, находящаяся в области, которой не было в предыдущем кадре, рисуется правильно.Однако зелье, которое было там раньше, остается исходным изображением.Это означает, что после нескольких поворотов появляется квадрат исходного вертикального изображения, а затем прямоугольник ниже или слева от повернутого изображения.

2) Когда я изменяю размер окна, изображение перерисовывается (как должно) в исходной вертикальной ориентации (а не должно).

По сути, я прихожу к выводу, что NSAffineTransform работает не так, как я думаю.Есть ли другой способ повернуть (и перевести) изображение?Спасибо

большой кусок кода:(код между «WORKS» и «endworks» — это рабочий код, позволяющий просто нарисовать изображение.Это из моего предыдущего вопроса).

[СТАРЫЙ КОД УДАЛЕН, заменен на новый код ниже]

Спасибо

РЕДАКТИРОВАТЬ:Еще немного исследований показало, что вместо NSAffineTtransform я могу вращать представление.Кажется, это работает лучше.Однако я не могу заставить перевод работать правильно.новый код ниже (исходный код удален для экономии места)

- (void)drawRect:(NSRect)rect
{

//WORKS
    NSRect frame;
    frame.origin = NSZeroPoint;
    frame.size = [image size];
// end works

    float deltaX, deltaY, height, width;

// if the rotate button was just clicked, we need to rotate by 90 deg, otherwise not
    double rotateDeg = justRot ? -90.0 : 0;

    justRot = NO;

// rotate

    deltaX = 0;
    deltaY = 0;

// translate to account for rotation

    height = [image size].height;
    width = [image size].width;

    switch (rotation)
    {
        case 0:
            NSLog(@"No rotation ");
            break;
        case 1: 
            deltaX += width;
            break;
        case 2:
            deltaX += width;
            deltaY +=  height;  
            break;
        case 3:
            deltaY += height;
            break;
    }


    NSPoint orig;
    if (rotation != 0)
    {
        orig.x = -100;
        orig.y = -100;
    }
    [self rotateByAngle: rotateDeg];
    NSLog(@"orig %f %f", orig.x, orig.y);
//  WORKS
    [self setFrame: frame];
    [image drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
// end works
    [self translateOriginToPoint: orig];    
}
Это было полезно?

Решение

Хорошо, для истории, если у кого-то еще возникнет этот вопрос, вот ответ, который я придумал:

Вращение кадра остается в drawRect, все остальное перемещается в метод Rotate:

-(void)rotate
{
    float deltaX, deltaY, height, width;

    rotation = (rotation +1) % 4 ;

    deltaX = 0;
    deltaY = 0;

// translate to account for rotation

    height = [image size].height;
    width = [image size].width;

    switch (rotation)
    {
        case 0:
            NSLog(@"No rotation ");
            deltaY -= width;
        break;
        case 1: 
            deltaY -= height;
            break;
        case 2:
            deltaX += height-width;
            deltaY -= height ;  
            break;
        case 3:
            deltaX += height-width;
            deltaY -= width;
            break;
    }

    NSPoint orig;
    orig.x = deltaX;
    orig.y = deltaY;

    [self rotateByAngle: 90.0];
    [self translateOriginToPoint: orig];

    [self setNeedsDisplay:YES];
}

Другие советы

Я предполагаю, что вы хотели бы повернуть изображение вокруг его центра.В этом случае вам нужно переместить начало аффинного преобразования в центр изображения, затем повернуть, а затем перевести обратно.Теперь, если у вас остались артефакты предыдущей позиции, возможно, это потому, что вы не вызвали -[NSView setNeedsDisplayInRect:] с правильными прямоугольниками.Помните, что вам необходимо аннулировать как предыдущую, так и новую позицию изображения.

Обновлять:Я только что заметил, что вы меняете рамку представления изнутри drawRect:.Уже слишком поздно менять рамку.Вместо этого нарисуйте изображение в правильном месте, не меняя рамку вида.

Взгляните на мой старый пример кода Transformed Image: http://developer.apple.com/mac/library/samplecode/Transformed_Image/index.html

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top