一些常用旋轉常量
#define M_E 2.71828182845904523536028747135266250 e
#define M_LOG2E 1.44269504088896340735992468100189214 log 2e
#define M_LOG10E 0.434294481903251827651128918916605082 log 10e
#define M_LN2 0.693147180559945309417232121458176568 log e2
#define M_LN10 2.30258509299404568401799145468436421 log e10
#define M_PI 3.14159265358979323846264338327950288 pi
#define M_PI_2 1.57079632679489661923132169163975144 pi/2
#define M_PI_4 0.785398163397448309615660845819875721 pi/4
#define M_1_PI 0.318309886183790671537767526745028724 1/pi
#define M_2_PI 0.636619772367581343075535053490057448 2/pi
#define M_2_SQRTPI 1.12837916709551257389615890312154517 2/sqrt(pi) #define M_SQRT2 1.41421356237309504880168872420969808 sqrt(2)
#define M_SQRT1_2 0.707106781186547524400844 362104849039 1/sqrt(2)
CGAffineTransformMakeTranslation(width, 0.0);是改變位置的,
CGAffineTransformRotate(transform, M_PI);是旋轉的。
CGAffineTransformMakeRotation(-M_PI);也是旋轉的
transform = CGAffineTransformScale(transform, -1.0, 1.0);是縮放的。
view.transform = CGAffineTransformIdentity;線性代數裏面講的矩陣變換,這個是恆等變換 當你改變過一個view.transform屬性或者view.layer.transform的時候需要恢復默認狀態的話,記得先把他們重置可以使用 view.transform = CGAffineTransformIdentity, 或者view.layer.transform = CATransform3DIdentity。
假設你一直不斷的改變一個view.transform的屬性,而每次改變之前沒有重置的話,你會發現後來的改變和你想要的發生變化了,不是你真正想要的結果
Quartz轉換實現的原理:Quartz把繪圖分成兩個部分,
用戶空間,即和設備無關,
設備空間,
用戶空間和設備空間中間存在一個轉換矩陣 : CTM
本章實質是講解CTM
Quartz提供的3大功能
移動,旋轉,縮放
演示如下,首先加載一張圖片
void CGContextDrawImage (
CGContextRef c,
CGRect rect,
CGImageRef image
);
移動函數
CGContextTranslateCTM (myContext, 100, 50);
旋轉函數
include
static inline double radians (double degrees) {return degrees * M_PI/180;}
CGContextRotateCTM (myContext, radians(–45.));
縮放
CGContextScaleCTM (myContext, .5, .75);
翻轉, 兩種轉換合成後的效果,先把圖片移動到右上角,然後旋轉180度
CGContextTranslateCTM (myContext, w,h);
CGContextRotateCTM (myContext, radians(-180.));
Quartz 2D編程指南(5)
我們可以通過操作CTM(current transformation matrix)來修改默認的用戶空間。在創建圖形上下文後,CTM是單位矩陣,我們可以 使用 Quartz 的變換函數來修改CTM,從而修改用戶空間中的繪製操作。
本章內容包括:
- 變換操作函數概覽
- 如何修改CTM
- 如何創建一個仿射變換
- 如何選擇兩個相同的變換
- 如何獲取user-to-device-space變換
我們可能使用 Quartz 內置的變換函數方便的平移、旋轉和縮放我們的繪圖。只需要短短几行代碼,我們便可以按順序應用變換或結合使用變換。圖5-1顯示了縮放和旋轉一幅 圖片 的效果。我們使用的每個變換操作都更新了CTM。CTM總是用於表示用戶空間和設備空間的當前映射關係。這種映射確保了應用程序的輸出在任何顯示器或打印機上看上去都很棒。
Quartz 2D API提供了5個函數,以允許我們獲取和修改CTM。我們可以旋轉、平移、縮放CTM。我們還可以聯結一個仿射變換矩陣。
有時我們可以不想操作用戶空間,直到我們決定將變換應用到CTM時, Quartz 爲此允許我們創建應用於此的仿射矩陣。我們可以使用另外一組函數來創建仿射變換,這些變換可以與CTM聯結在一起。
我們可以不需要了解矩陣的數學含義而使用這些函數。
修改CTM
我們在繪製圖像前操作CTM來旋轉、縮放或平移page,從而變換我們將要繪製的對象。以變換CTM之前,我們需要保存圖形狀態,以便繪製後能恢復。我們同樣能用仿射矩陣來聯結CTM。在本節中,我們將介紹與CTM函數相關的四種操作--平移、旋轉、縮放和聯結。
假設我們提供了一個可用的圖形上下文、一個指向可繪製圖像的矩形的指針和一個可用的CGImage對象,則下面一行代碼繪製了一個圖像。該行代碼可以繪製如圖5-2所示的圖片。在閱讀了本節餘下的部分後,我們將看到如何將變換應用於圖像。
複製代碼
|
平移變換根據我們指定的x, y軸的值移動座標系統的原點。我們通過調用CGContextTranslateCTM函數來修改每個點的x, y座標值。如圖5-3顯示了一幅圖片沿x軸移動了100個單位,沿y軸移動了50個單位。具體代碼如下:
複製代碼
|
旋轉變換根據指定的角度來移動座標空間。我們調用CGContextRotateCTM函數來指定旋轉角度(以弧度爲單位)。圖5-4顯示了圖片以原點(左下角)爲中心旋轉45度,代碼所下所示:
複製代碼
|
由於旋轉操作使圖片的部分區域置於上下文之外,所以區域外的部分被裁減。我們用弧度來指定旋轉角度。如果需要進行旋轉操作,下面的代碼將會很有用
複製代碼
|
複製代碼
|
聯合變換將兩個矩陣相乘來聯接現價變換操作。我們可以聯接多個矩陣來得到一個包含所有矩陣累積效果矩陣。通過調用CGContextConcatCTM來聯接CTM和仿射矩陣。
另外一種得到累積效果的方式是執行兩個或多個變換操作而不恢復圖形狀態。圖5-6顯示了先平移後旋轉一幅圖片的效果,代碼如下:
複製代碼
|
圖5-7顯示了平移、縮放和旋轉一幅圖片,代碼如下:
複製代碼
|
變換操作的順序會影響到最終的效果。如果調換順序,將得到不同的結果。調換上面代碼的順序將得到如圖5-8所示的效果,代碼如下:
複製代碼
|
創建仿射變換
仿射變換操作在矩陣上,而不是在CTM上。我們可以使用這些函數來構造一個之後用於CTM(調用函數CGContextConcatCTM)的矩陣。仿射變換函數使用或者返回一個CGAffineTransform數據對象。我們可以構建簡單或複雜的仿射變換。
仿射變換函數能實現與CTM函數相同的操作--平移、旋轉、縮放、聯合。表5-1列出了仿射變換函數及其用途。注意每種變換都有兩個函數。
表5-1 仿射變換函數
函數 | 用途 |
CGAffineTransformMakeTra nslation | 通過指定x, y值來創建一個平移矩陣 |
CGAffineTransformTransla te | 在已存在的矩陣中使用平移 |
CGAffineTransformMakeRot ation | 通過指定角度來創建一個旋轉矩陣 |
CGAffineTransformRotate | 在已存在的矩陣中使用旋轉 |
CGAffineTransformMakeSca le | 通過指定x, y縮放因子來創建一個縮放矩陣 |
CGAffineTransformScale | 在已存在的矩陣中使用縮放 |
在一些情況下,我們可能不需要變換整修空間,而只是一個點或一個大小。我們通過調用CGPointApplyAffineTransform在CGPoint結構上執行變換操作。調用CGSizeApplyAffineTransform在CGSize結構上執行變換操作。調用CGRectApplyAffineTransform在CGRect結構上執行變換操作。CGRectApplyAffineTransform返回一個最小的矩形,該矩形包含了被傳遞給CGRectApplyAffineTransform的矩形對象的角點。如果矩形上的仿射變換操作只有縮放和平移操作,則返回的矩形與四個變換後的角組成的矩形是一致的。
可以通過調用函數CGAffineTransformMake來創建一個新的仿射變換,但與其它函數不同的是,它需要提供一個矩陣實體。
評價仿射變換
我們可以通過調用CGAffineTransformEqualToTransform函數來決定一個仿射變換是否與另一個相同。如果兩個變換相同,則返回true;否則返回false。
函數CGAffineTransformIsIdentity用於確認一個變換是否是單位變換。單位變換沒有平移、縮放和旋轉操作。 Quartz 常量CGAffineTransformIdentity表示一個單位變換。
獲取用戶空間到設備空間的變換
當使用 Quartz 2D時,我們只是在用戶空間下工作。 Quartz 爲我們處理用戶空間和設備空間的轉換。如果我們的應用程序需要獲取 Quartz 轉換用戶空間和設備空間的仿射變換,我們可以調用函數CGContextGetUserSpaceToDeviceSpaceTransform。
Quartz 提供了一系列的函數來轉換用戶空間和設備空間的幾何體。我們會發現這些函數使用趕來比使用CGContextGetUserSpaceToDeviceSpaceTransform函數返回的仿射變換更好用。
- 點:函數CGContextConvertPointToDeviceSpace和CGContextConvertPointToUserSpace將一個CGPoint數據結構從一個空間變換到另一個空間。
- 大小:函數CGContextConvertSizeToDeviceSpace和CGContextConvertSizeToUserSpace將一個CGSize數據結構從一個空間變換到另一個空間。
- 矩形:函數CGContextConvertRectToDeviceSpace和CGContextConvertRectToUserSpace將一個CGPoint數據結構從一個空間變換到另一個空間。