Могу ли я переместить начало координат при выполнении преобразования вращения в Quartz 2D для iPhone? - PullRequest
8 голосов
/ 22 марта 2009

Извините, если это очевидно или рассматривается в другом месте, но я весь день гуглю и не нашел решения, которое действительно сработало.

Моя проблема заключается в следующем: в настоящее время я рисую изображение в полноэкранном режиме UIView, для примера скажем, что изображение находится в правом нижнем углу UIView. Я хотел бы сделать преобразование вращения (CGAffineTransformMakeRotation) в центре этого изображения, однако по умолчанию команда вращения вращается вокруг центра UIView самостоятельно. В результате мое изображение перемещается по экрану, когда я поворачиваюсь, вместо того чтобы оставаться на месте и вращаться вокруг своего собственного центра.

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

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

// Before this i'd make a call to a function that draws a path to a passed in context
CGAffineTransform inverseTranslation = CGAffineTransformMakeTranslation( transX, transY );
CGAffineTransform translation = CGAffineTransformMakeTranslation( -transX, -transY );
CGAffineTransform rot = CGAffineTransformMakeRotation( 3.14 );
CGAffineTransform final = CGAffineTransformConcat( CGAffineTransformConcat( inverseTranslation, rot ), translation );
// Then i apply the transformation animation like normal using self.transform = final etc etc

Я также пробовал такие вещи, как CGContextTranslateCTM и CGContextSaveGState / UIGraphicsPushContext, но, похоже, они малоэффективны.

Я боролся с этим уже несколько дней, и мое текущее решение кажется близким, но я понятия не имею, как избавиться от этой переводящей анимации. У кого-нибудь есть решение для этого или лучший способ сделать это?

[обновление] В настоящее время я рисую свое изображение по центру в центре UIview, а затем устанавливаю свойство UIView.center в исходное положение, которое я хотел бы повернуть, а затем выполняю команду rotate. Похоже, что-то вроде хака, но пока я не смогу заставить работать реальные переводы, это мой единственный выбор. Спасибо!

Ответы [ 4 ]

14 голосов
/ 02 июня 2009

duncanwilcox 'правильный ответ, но он пропустил ту часть, где вы меняете якорь слоя вида на точку, вокруг которой хотите вращаться.

CGSize sz = theview.bounds.size;
// Anchorpoint coords are between 0.0 and 1.0
theview.layer.anchorPoint = CGPointMake(rotPoint.x/sz.width, rotPoint.y/sz.height);
[UIView beginAnimations:@"rotate" context:nil];
theview.transform = CGAffineTransformMakeRotation( 45. / 180. * M_PI );
[UIView commitAnimations];

Это задокументировано здесь: http://developer.apple.com/documentation/Cocoa/Conceptual/CoreAnimation_guide/Articles/Layers.html

7 голосов
/ 23 апреля 2012

Это тоже вариант: простая смена базы; -)

CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
transform = CGAffineTransformRotate(transform, angle);
transform = CGAffineTransformTranslate(transform,-x,-y);

где (x,y) - центр вращения, который вам нравится

2 голосов
/ 27 марта 2009

Вращение происходит вокруг точки привязки слоя вида. По умолчанию для точки привязки является центр (0,5, 0,5), поэтому достаточно одного поворота без перевода.

Сделал быстрый тест, и это работает для меня:

[UIView beginAnimations:@"rotate" context:nil];
self.transform = CGAffineTransformMakeRotation( 45. / 180. * 3.14 );
[UIView commitAnimations];
1 голос
/ 27 марта 2009

Если вы не хотите, чтобы анимация происходила , а просто установите новое вращение, вы можете использовать это:

CGFloat newRotation = 3.14f 

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.0]; // no tweening
CGAffineTransform transform = CGAffineTransformMakeRotation(newRotation);
self.transform = transform;
[UIView commitAnimations];

Вращение действительно должно происходить вокруг центра UIView. Установка animationDuration на ноль гарантии, анимация не должна происходить.

Будьте уверены, что вы не делаете это 60 раз в секунду. С этими инструментами очень заманчиво создавать игры, похожие на анимацию. Анимации такого типа не предназначены для покадровой игры «множество спрайтов, летающих повсюду».

Для этого - и я пошел по этому пути - единственный путь - OpenGL.

...