2012-05-12 52 views
0

我想縮放+翻譯視圖,然後將此轉換製作回來。但是CGAffineTransformInvert返回一個轉換,它做了一些不同的事情(無法理解它的邏輯)。CGAffineTransformInvert不會反轉視圖轉換

#import <UIKit/UIKit.h> 
@interface TestView : UIView { 
    UIView *view; 
    CGAffineTransform transform; 
} 
@end 


#import "TestView.h" 
#import <QuartzCore/QuartzCore.h> 
@implementation TestView 
- (void)testAnimation:(NSString*)animationID finished:(NSNumber*)finished context:(void*)context { 
    CGAffineTransform transformInverted = CGAffineTransformInvert(transform); 
    [UIView beginAnimations:@"test2" context:NULL]; 
    [UIView setAnimationDuration:3.0]; 
    [UIView setAnimationCurve:UIViewAnimationCurveLinear]; 
    view.transform = transformInverted; 
    [UIView commitAnimations]; 
} 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code 
     view = [[UIView alloc] initWithFrame:CGRectMake(150, 150, 100, 100)]; 
     view.backgroundColor = [UIColor greenColor]; 
     [self addSubview:view]; 

     CGAffineTransform transform1 = CGAffineTransformTranslate(view.transform, -150, -150); 
     transform = CGAffineTransformScale(transform1, (float)1/2, (float)1/2); 

     [UIView beginAnimations:@"test1" context:NULL]; 
     [UIView setAnimationDuration:3.0]; 
     [UIView setAnimationCurve:UIViewAnimationCurveLinear]; 
     [UIView setAnimationDelegate:self]; 
     [UIView setAnimationDidStopSelector:@selector(testAnimation:finished:context:) ]; 

     view.transform = transform; 

     [UIView commitAnimations]; 
    } 
    return self; 
} 
+0

嘗試更換語句 view.transform = transformInverted; with view.transform = CGAffineTransformConcat(view.transform,transformInverted); –

回答

5

CGAffineTransformInvert顛倒變換矩陣,並返回一個矩陣,該矩陣乘以CGAffineTransformIdentity中的原始結果。

如果您想翻譯翻譯/比例尺,您應該自己跟蹤它們。

PS。矩陣非常複雜,它們不存儲平移/縮放/旋轉值,它們由幾個值組成,當乘以座標時會給出翻譯/縮放/旋轉值,所以您不能期望反轉矩陣並獲得翻譯,縮放和旋轉的矩陣。

您可以閱讀更多關於它們的信息here

編輯回答您的評論:

當與矩陣的工作,操作順序是相當重要的,如果旋轉和平移,然後,結果將是,如果你翻譯,然後旋轉比不同。

要扭轉操作應用於矩陣,你應該應用相反的操作以相反的順序,在這種情況下,要扭轉這種:

CGAffineTransform transform1 = CGAffineTransformTranslate(view.transform, x1, x2); 
CGAffineTransform transform2 = CGAffineTransformScale(transform1, r1, r2); 
CGAffineTransform transform3 = CGAffineTransformRotate(transform2, a); 

你需要做到這一點:

CGAffineTransform reversed3 = CGAffineTransformRotate(transform3, -a); 
CGAffineTransform reversed2 = CGAffineTransformScale(reversed3, 1/r1, 1/r2); 
CGAffineTransform reversed1 = CGAffineTransformTranslate(reversed2, -x1, -x2); 

[view setTransform:reversed1]; 

如果您還沒有修改視圖的轉換之前,你可以這樣做:

[view setTransform:CGAffineTransformIdentity]; 

哪是零旋轉,零轉換,並且標度爲1.

+0

謝謝。現在我明白了 - 我無法期待這一點。其實我需要反轉CGAffineTransform transform1 = CGAffineTransformTranslate(view.transform,x1,x2); CGAffineTransform transform2 = CGAffineTransformScale(transform1,r1,r2); CGAffineTransform transform3 = CGAffineTransformRotate(transform2,a); 如果你很容易告訴我如何? – maxgrinev

+0

我編輯了我的答案以回答評論中的問題。希望它能幫助 – EmilioPelaez

+0

非常感謝。操作順序很重要!現在它運作完美。 – maxgrinev

0

我不知道我明白你正在嘗試做的,但你不應該簡單地更改視圖的轉換回CGAffineTransformIdentity在testAnimation方法?

+0

感謝您的回答。我想*回動畫,而不是隻放置在原始位置。結合兩個動畫時(例如縮放+平移或旋轉+平移),結果變得不容易,因爲縮放/旋轉以某種方式修改了traslate行爲。我不明白如何。 – maxgrinev

+0

你是否試過用翻譯作爲例子?只要好奇至少基本工作。 – mprivat

+0

變換矩陣是最終結果。它編碼了一系列變化,但不是你如何到達那裏。如果您在多個步驟中執行動畫,則需要反向顯式執行這些步驟以便向後運行動畫。另外,連接變換矩陣相當混亂。我總是不得不挖掘一本關於動畫的書來找出應用轉換的順序以獲得期望的效果。我建議尋找一本關於3D圖形的好書。大多數將覆蓋連接轉換背後的數學。 –

0

考慮下面的代碼。 這裏我們有transformTest,然後我們在其上應用transform3。然後我們在transform3的結果逆向上應用。最終結果更接近transformTest(浮點精度更低)。

如果你想在你的代碼中做view.transform = CGAffineTransformConcat(view.transform, transformInverted);它將工作。這一個

CGAffineTransform transformStart = CGAffineTransformIdentity; 
CGAffineTransform transform1 = CGAffineTransformTranslate(transformStart, 10, 23); 
CGAffineTransform transform2 = CGAffineTransformScale(transform1, 2, 10); 
CGAffineTransform transform3 = CGAffineTransformRotate(transform2, M_PI_4); 

CGAffineTransform invertedTransform = CGAffineTransformInvert(transform3); 


// here actual test 
NSLog(@"--------------- here actual test ---------------"); 

CGAffineTransform transformTest = CGAffineTransformMakeTranslation(2, 15); 
transformTest = CGAffineTransformRotate(transformTest, M_PI_2); 
transformTest = CGAffineTransformScale(transformTest, 19, 0.4); 
transformTest = CGAffineTransformTranslate(transformTest, -33, -19); 
NSLog(@"transformTest %@", NSStringFromCGAffineTransform(transformTest)); 

CGAffineTransform transformTestMultiplied = CGAffineTransformConcat(transformTest, transform3); 
NSLog(@"transformTestMultiplied %@", NSStringFromCGAffineTransform(transformTestMultiplied)); 

CGAffineTransform transformTestMultipliedByInverse = CGAffineTransformConcat(transformTestMultiplied, invertedTransform); 
NSLog(@"transformTestMultipliedByInverse %@", NSStringFromCGAffineTransform(transformTestMultipliedByInverse)); 

輸出:

2016-07-19 13:49:22.034 testUIView[45050:69431115] --------------- here actual test --------------- 
2016-07-19 13:49:22.034 testUIView[45050:69431115] transformTest [1.1634144591899855e-15, 19, -0.40000000000000002, 2.4492935982947065e-17, 9.5999999999999623, -612] 
2016-07-19 13:49:22.034 testUIView[45050:69431115] transformTestMultiplied [-26.870057685088803, 134.35028842544403, -0.56568542494923812, -2.8284271247461898, 889.0751503711158, -4236.611249867763] 
2016-07-19 13:49:22.034 testUIView[45050:69431115] transformTestMultipliedByInverse [0, 19, -0.40000000000000002, 0, 9.5999999999999162, -612]