2009-03-22 6 views
8

죄송합니다. 분명하거나 다른 곳에서 다루어 지지만, 하루 종일 인터넷 검색을 해봤지만 실제로 효과가있는 해결책을 찾지 못했습니다.iPhone 용 Quartz 2D에서 회전 변환을 할 때 원점을 이동할 수 있습니까?

내 문제는 다음과 같습니다. 현재 전체 화면 UIView에서 이미지를 그리는 중입니다. 예를 들어 이미지가 UIView의 오른쪽 아래에 있다고 가정합니다. 그 이미지의 중심에서 회전 변환 (CGAffineTransformMakeRotation)을하고 싶습니다. 그러나 기본적으로 회전 명령은 UIView의 중심을 중심으로 회전합니다. 결과적으로, 내 이미지가 회전 할 때 화면을 돌아 다니며 그 자리에 머무르고 자체 중심을 중심으로 회전합니다.

내가 수집 한 것부터, 원점 (UIView 중심)이 내 이미지의 중심에 있고, 회전하고, 원래 위치로 다시 변환하여 컨텍스트를 복원 할 수 있도록 컨텍스트를 변환해야합니다.

다음은 내가 가장 잘한 일이지만, 이미지가 회전하는 동안 회전하는 동안 아래로 움직이는 것이 문제입니다. 나는

// 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 

...이 첫 번째 단계는 번역하고 3 단계 대신 상대를 번역의 시작과 끝 지점이 동일 할 것이라고 실현의 번역 트위닝 애니메이션에 의한 생각 나는 또한 같은 물건을 시도했습니다 CGContextTranslateCTM 및 CGContextSaveGState/UIGraphicsPushContext를 사용하지만 거의 영향을 미치지 않는 것 같습니다.

저는 며칠 동안이 문제를 해결하기 위해 노력해 왔지만 현재의 솔루션은 가까운 것처럼 보입니다. 그러나 번역 트위닝을 없애는 방법에 대한 단서가 없습니다. 누구든지 이것에 대한 해결책을 갖고 있습니까?

[업데이트] 당분간 나는 UIview의 중심에 이미지를 그려서 UIView.center 속성을 회전하고 회전 명령을 수행하려는 원점으로 설정합니다. 약간의 해킹처럼 보이지만 실제로 작동하는 번역본을 얻을 때까지 내 유일한 선택입니다. 감사합니다.

답변

14

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

+2

pi 값으로 작업 할 때 math.h 상수를 사용해야한다는 것을 보여주기 위해 quick comment- edited. M_PI_4, M_PI_2, M_PI는 모든 반올림 오류보다 정확하고 정확합니다. :) –

2

회전은보기 레이어의 앵커 포인트 주위에서 발생합니다. anchorPoint의 기본값은 가운데 (0.5, 0.5)이므로 변환없이 회전만으로 충분합니다.

가 빠른 테스트를했고이 나를 위해 작동합니다 : 당신이 애니메이션이 발생하지 않으 경우

[UIView beginAnimations:@"rotate" context:nil]; 
self.transform = CGAffineTransformMakeRotation(45./180. * 3.14); 
[UIView commitAnimations]; 
+0

좋아 내 설명은 약간 오도했다. 문맥에서 뭔가를 그리는 것입니다. (이미지라고 부르지 만 컨텍스트 명령을 사용하여 그리는 것일뿐입니다) 컨텍스트의 중심에 있지 않습니다. 컨텍스트의 중심이 내 "이미지"의 중심에있는 것처럼 회전하고 싶습니다. – Skyler

+0

pi 값으로 작업 할 때 math.h 상수를 사용해야한다는 것을 보여주기 위해 quick comment- edited. M_PI_4, M_PI_2, M_PI가 모든 반올림 오류보다 더 정확하고 정확합니다. –

1

, 그러나 다만 새로운 회전을 설정, 당신은이를 사용할 수 있습니다

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을 0으로 설정하면 경고가 트위닝되지 않습니다.

초당 60 회하지 마십시오. 이러한 도구로 애니메이션과 같은 게임을 만드는 것은 매우 유혹적입니다. 이러한 종류의 애니메이션은 "모든 곳을 비행하는 많은 스프라이트"를 기반으로 한 프레임 기반의 게임이 아닙니다.

그 길을 가고 있습니다. 갈 길은 OpenGL입니다.

+0

CGFIextTranslateCTM이 작동하지 않았으므로 글자 회전을위한 애니메이션을 원합니다. 사전 및 게시물 번역에 0 초 길이를 사용할 수 있습니다. .. – Skyler

+0

CGContextTranslateCTM을하기 전에 CGContext 상태를 저장했는지 확인하십시오. 그런 다음 상태를 복원하십시오. 컨텍스트에서 드로잉 한 후에 CTM을 번역하면 효과가 없습니다. – Kriem

7

이것은 또한 옵션입니다 : (x,y)가 회전 중심이 기준 ;-)

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

의 간단한 변경 당신은 아마도