2011-11-26 79 views
35

如何使用CGAffineTransformMake()的單個調用加上math.h trig函數(如sin(),cos()等)圍繞角度α的點x,y旋轉Core Graphics仿射變換,並沒有其他CG電話。繞點旋轉的一步仿射變換?

這裏的其他答案似乎是使用多個堆疊轉換或多步轉換來移動,旋轉和移動,使用多個Core Graphics調用。這些答案不符合我的具體要求。

+2

爲什麼你需要'CGAffineTransformMake()'一個電話嗎?堆疊調用產生完全相同的結果,除非它們以可讀和有意義的方式進行。如果你真的想在一次通話中做到這一點,那麼你最終會複製在堆棧調用中使用的相同數學計算,絕對不會有好處。 –

+3

這可能是什麼要求?您可以使用CGAffineTransformConcat將這些「堆棧」轉換組合成一個CGAffineTransform。結果將與單個組件的公式相同,並且所涉及的計算內部將相同,或者在CGAffineTransformConcat的情況下可能更優化。 – morningstar

+0

我想要矩陣方程式用於不同(不一定是歐幾里得)幾何二維空間中的匹配但非圖形模型對象。 – hotpaw2

回答

101

角度的繞點的旋轉(X,Y)對應的仿射變換:

CGAffineTransform transform = CGAffineTransformMake(cos(a),sin(a),-sin(a),cos(a),x-x*cos(a)+y*sin(a),y-x*sin(a)-y*cos(a)); 

您可能需要-a,而不是堵塞一個取決於你是否要旋轉是順時針或逆時針。此外,您可能需要插入-y而不是y,具體取決於您的座標系是否顛倒。

此外,您還可以使用恰好做到了同樣的事情在三行代碼:

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

如果你將其應用到一個視圖,你也可以簡單地使用旋轉通過CGAffineTransformMakeRotation變換(一)前提是您設置視圖的圖層的anchorPoint屬性以反映您想要旋轉的點。但是,聽起來像你不希望將其應用於視圖。最後,如果您將此應用於非歐幾里得2D空間,您可能根本不需要仿射變換。仿射變換是歐氏空間等距的,這意味着它們保存了標準的歐氏距離,以及角度。如果你的空間不是歐幾里得,那麼你要轉型實際上可能不是仿射,或者如果它是仿射,對於旋轉矩陣可能不會像我上面所說的用正弦和餘弦寫一樣簡單。舉例來說,如果你在一個雙曲空間,你可能需要使用雙曲三角函數的sinh和COSH,用不同的+和沿 - 標誌在公式中。

P.S.我也想提醒任何人閱讀這遠說,「親和」的發音是一個短暫的「一」,如「問」,不長的「一」,如「能」。我甚至聽到蘋果員工在他們的WWDC會談中誤報了它。

+1

究竟是什麼? – jjxtra

+1

'a'是以弧度表示的角度,它似乎是 – Curtis

+2

如果您要提供有關發音的提示,那麼您還應該指定它是否與「feen」中的「fine」或「fine」一樣細。但也許我是唯一一個讓這部分錯誤的人。 : -/ –

1

退房此鏈接:Rotating an iPhone View Around a Point。它可能會幫助你。在文章的底部,有一個標題爲「更改錨點」的部分。這可能是最適合您的需求的,儘管爲了不抵消該觀點,必須進行一些補償。

2

對於像我這樣的人來說,他們正在努力尋找一個完整的解決方案來旋轉圖像並適當地縮放它,以便填充包含框架,幾個小時後這是最完整和無瑕的解決方案,我已經獲得。

這裏的技巧是在涉及任何轉換(包括比例和旋轉)之前轉換參考點。之後,您必須連接兩個變換以獲得完整的仿射變換。

我已將整個解決方案打包在CIFilter子類中,您可以gist here

下面這段代碼的相關部分:

CGFloat a = _inputDegree.floatValue; 
CGFloat x = _inputImage.extent.size.width/2.0; 
CGFloat y = _inputImage.extent.size.height/2.0; 

CGFloat scale = [self calculateScaleForAngle:GLKMathRadiansToDegrees(a)]; 

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


CGAffineTransform transform2 = CGAffineTransformMakeTranslation(x, y); 
transform2 = CGAffineTransformScale(transform2, scale, scale); 
transform2 = CGAffineTransformTranslate(transform2,-x,-y); 

CGAffineTransform concate = CGAffineTransformConcat(transform2, transform);