2009-10-01 11 views

Odpowiedz

5

Weź asin() lub acos() afinicznego członka b lub c.

struct CGAffineTransform { 
    CGFloat a; 
    CGFloat b; 
    CGFloat c; 
    CGFloat d; 
    CGFloat tx; 
    CGFloat ty; 
}; 
+4

Matematyka za to wyjaśniono w "Math Za matryc" podsekcji Programming Guide Quartz 2D: http: // developer.apple.com/mac/library/DOCUMENTATION/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_affine/dq_affine.html#//apple_ref/doc/uid/TP30001066-CH204-CJBECIAD –

+2

asin i acos nie są poprawne, gdy występuje skala. poprawna formuła to: CGFloat radians = atan2f (self.view.transform.b, self.view.transform.a); Stopnie CGFloat = radian * (180/M_PI); – lbsweek

0

Możesz spróbować użyć funkcji acos() i asin(), aby odwrócić to, co robi CGAffineTransformMakeRotation. Jednakże, ponieważ macie pomnożoną macierz przekształcenia skali, może to być nieco trudne.

0

że w przeszłości stosowane klasy XAffineTransform z zestawu narzędzi GeoTools wyodrębnić obrót z matrycy afinicznej. Działa nawet wtedy, gdy zastosowano skalowanie i ścinanie.

Jest to biblioteka Java, ale powinieneś być w stanie z łatwością przekonwertować ją na (Objective-) C. Możesz spojrzeć na the source for XAffineTransform here. (Metoda nazywa się getRotation.) Możesz też read the API here.

To jest serce metody:

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); 

trzeba by też realizować getScale/getShear metod. Wcale nie twardy. (W większości przypadków można po prostu skopiować kod Java jak jest.)

5
atan2(rotationTransform.b, rotationTransform.d) 

acos (b) rozwiązanie sugerowane przez kogoś jest ważny tylko w zakresie +/- 0.5pi. To rozwiązanie wydaje się być niezawodne w kombinacji rotacji, translacji i skalowania, chociaż prawie na pewno nie jest ścinaniem. Moja wcześniejsza odpowiedź (atan2(rotationTransform.b, rotationTransform.a) nie była odporna na skalowanie.

This duplicate was the basis for my original answer.

+2

Myślę, że powinno to być 'atan2 (rotationTransform.b, rotationTransform.d)' –

+0

Luiz - Są one takie same i poprawne pod kombinacjami translacji i obrotu, ale wydaje się, że twoje zachowanie pozostaje poprawne po dodaniu skalowania, więc idę zaktualizować. Dziękuję Ci. –

+0

using transform.b, transform.d zapisany dzień! Dzięki! – srik

0

asin i acos nie są poprawne, gdy występuje skala.

poprawna formuła brzmi:

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

czyli

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