Несоответствия CGAffineTransformRotate и M_PI (Objective-C, iOS)

Я пытаюсь делать простые вращения в Objective-C, и сразу возникает пара проблем. Одна вещь - это несоответствие, которое я получаю от CGAffineTransformRotate и то, как M_PI несовместим при использовании внутри этой функции.

Предположим, я сделаю это и прикреплю к кнопке. Когда я нажимаю его один раз, он поворачивается на 180 градусов против часовой стрелки (хорошо и соответствует документации), но когда я нажимаю его снова, он поворачивается на 180 по часовой стрелке, даже если значение не отрицательное. Изменение M_PI на -M_PI делает то же самое без различий в повороте:

[UIView animateWithDuration:secs delay:0.0 options:option
   animations:^{
      self.transform = CGAffineTransformRotate(self.transform, M_PI);   //Inconsistent
} completion:nil];

Теперь предположим, что я изменил M_PI на 3.141593, то есть значение, которое M_PI содержит, когда я его распечатываю. Теперь, когда нажимаю на кнопку, работает полностью нормально. Оба раза он повернется на 180 градусов против часовой стрелки. Когда я изменю его на -3.141593, он тоже будет работать полностью, по часовой стрелке:

self.transform = CGAffineTransformRotate(self.transform, 3.141593);   //Works

Когда я играю с ним больше, поведение становится более странным.

Предположим, я хочу повернуть на 90 градусов (пи / 2). M_PI теперь ведет себя так же, как и при использовании значения, но вращение противоположно тому, что должно быть:

//Should be Clockwise but rotates CounterClockwise
self.transform = CGAffineTransformRotate(self.transform, -M_PI/2);  
self.transform = CGAffineTransformRotate(self.transform, -1.5707965); 

//Should be CounterClockwise but rotates Clockwise
self.transform = CGAffineTransformRotate(self.transform, M_PI/2);  
self.transform = CGAffineTransformRotate(self.transform, 1.5707965);

И если я хочу повернуть что-либо более чем на 180 градусов (PI), я просто поверну самый короткий маршрут, даже если я указываю положительное или отрицательное вращение. Когда я поворачиваю на 360 градусов (2PI), он даже не вращается.

Почему это происходит и что я могу сделать, чтобы сделать это более последовательным? И второстепенный вопрос, который у меня есть, - как я могу вращать предметы на 270 и 360 градусов.


person FireDragonMule    schedule 08.10.2012    source источник


Ответы (2)


Проблема в том, что вы не можете реально контролировать направление вращения при использовании animateWithDuration. Он всегда будет выбирать кратчайший путь. При повороте на 180 градусов поведение не определено, потому что теоретически существует 2 возможности для кратчайшего маршрута. Это также объясняет, почему вы не можете поворачиваться более чем на 180 градусов. Если вы хотите иметь больший контроль над анимацией или делать более сложные анимации, используйте CAKeyframeAnimation.

person Felix    schedule 08.10.2012
comment
Почему при повороте pi / 2 (90) он вращается в положение 3pi / 2 (270) в противоположном направлении. - person FireDragonMule; 09.10.2012

Как сказал phix23: всегда выбирайте кратчайший путь. Таким образом, вы можете избежать этого, используя этот трюк, например, чтобы пройти полный круг по часовой стрелке: вы должны разделить круг, например, на 3 контрольные точки:

[UIView animateWithDuration:secs delay:0.0 options:UIViewAnimationOptionCurveLinear
animations:^{
   self.transform = CGAffineTransformRotate(self.transform, M_PI_2/3);   
} completion:(BOOL end)
{
       [UIView [UIView animateWithDuration:secs delay:0.0
                                   options:UIViewAnimationOptionCurveLinear
  animations:^{
      self.transform = CGAffineTransformRotate(self.transform, -M_PI_2/3);
  } completion:(BOOL end)
  {
  }

}

];

Этот код не тестировался, поэтому, если есть проблема, попробуйте поиграть с ним. Надеюсь, это поможет.

person Dima Deplov    schedule 10.11.2013