Получите только вращение из CGAffineTransform

Можно ли получить только угол поворота из CGAffineTransform, который также имеет значения перемещения и масштабирования? Если да, то как?

Заранее спасибо!


person Pieter Jongsma    schedule 01.10.2009    source источник


Ответы (5)


Возьмите asin () или acos () аффинного члена b или c.

struct CGAffineTransform {
   CGFloat a;
   CGFloat b;
   CGFloat c;
   CGFloat d;
   CGFloat tx;
   CGFloat ty;
};
person zaph    schedule 01.10.2009
comment
Математика, лежащая в основе этого, объясняется в подразделе «Математика за матрицами» Руководства по программированию Quartz 2D: developer.apple.com/mac/library/DOCUMENTATION/GraphicsImaging/. - person Brad Larson; 01.10.2009
comment
asin и acos неверны, когда есть масштаб. правильная формула: CGFloat радианы = atan2f (self.view.transform.b, self.view.transform.a); CGFloat градусы = радианы * (180 / M_PI); - person lbsweek; 25.02.2014


Вы можете попробовать использовать функции acos () и asin (), чтобы отменить то, что CGAffineTransformMakeRotation делает. Однако, поскольку у вас есть матрица преобразования масштаба, умноженная на нее, это может быть немного сложно сделать.

person Dave DeLong    schedule 01.10.2009

В прошлом я использовал класс XAffineTransform из набора инструментов GeoTools для извлечения поворота из аффинной матрицы. Он работает даже при применении масштабирования и резки.

Это библиотека Java, но вы сможете легко преобразовать ее в (Objective-) C. Вы можете посмотреть источник XAffineTransform здесь. (Метод называется getRotation.) И вы можете прочтите API здесь.

В этом суть метода:

final double scaleX = getScaleX0(tr);
final double scaleY = getScaleY0(tr) * flip;
return Math.atan2(tr.getShearY()/scaleY - tr.getShearX()/scaleX,
                  tr.getScaleY()/scaleY + tr.getScaleX()/scaleX);

Вам также потребуется реализовать методы getScale / getShear. Совсем не сложно. (По большей части вы можете просто скопировать код Java как есть.)

person Felixyz    schedule 01.10.2009

asin и acos неверны, когда есть масштаб.

правильная формула:

CGFloat radians = atan2f(self.view.transform.b, self.view.transform.a); 
CGFloat degrees = radians * (180 / M_PI); 

or:

CGFloat angle = [(NSNumber *)[view valueForKeyPath:@"layer.transform.rotation.z"] floatValue];
person lbsweek    schedule 25.02.2014