Core Graphics框架 :仿射變換與齊次座標
Core Graphics框架中的圖形變換
在Core Graphics框架圖形繪製的時候,經常會有對圖形進行平移、縮放、旋轉這樣的要求.那麼我們該如何實現呢?這就需要Core Graphics框架中的CGAffineTransform(矩陣)這個結構體來進行實現了.下面我們就對CGAffineTransform這個矩陣結構體,進行逐一的說明.
CGAffineTransform與齊次座標
首先,我們先看一下CGAffineTransform這個結構體是什麼樣子的,如下所示.
struct CGAffineTransform {
CGFloat a, b, c, d;
CGFloat tx, ty;
};
為了把二維圖形的變化統一在一個座標系裡,引入了齊次座標的概念,即把一個圖形用一個三維矩陣表示,其中第三列總是(0,0,1),用來作為座標系的標準.也就是z軸.是不發生改變的。接下來呢,我們就使用齊次座標來表示這個結構體.如下所示.
|a b 0|
|c d 0|
|tx ty 1|
現在我們就看一下用齊次座標是如何表示一個座標的仿射變換的,假設現在有座標 [X ,Y,1],運算原理如下所示.
|a b 0|
[X,Y, 1] |c d 0| = [aX + cY + tx bX + dY + ty 1] ;
|tx ty 1|
那麼平移、縮放、旋轉是怎麼執行的呢?其實很簡單,這三種形式的變換不過是齊次座標的幾個特殊情況,下面我們就一一道來.
平移變換
條件: a = d = 1 ,b = c = 0.
條件如上所述,接下來我們看一下座標 [X ,Y,1]與我們設定好的齊次座標的叉積會發生什麼樣的變化.
|1 0 0|
[X,Y, 1] |0 1 0| = [X + tx , Y + ty , 1] ;
|tx ty 1|
那麼的座標就變成了 [X + tx , Y + ty , 1],與原座標相比,z軸沒發生任何的改變,但是x軸方向平移了tx個單位,y軸方向平移了ty個單位.
那麼如果我們把這種特殊情況進行封裝,我們就得到了我們的平移函式.
CGAffineTransformMakeTranslation(CGFloat tx,CGFloat ty)
縮放變換
條件: b = c = 0 ,tx = ty = 0.
如平移變換一致,我們把條件輸入進去,看一下座標 [X ,Y,1]與我們設定好的齊次座標的叉積會發生什麼樣的變化.
|a 0 0|
[X,Y, 1] |0 d 0| = [aX , dY ,1] ;
|0 0 1|
那麼的座標就變成了[aX , dY ,1],與原座標相比,z軸仍然沒發生任何的改變,但是x軸方向縮放了a倍,y軸方向縮放了d倍.
那麼如果我們把這種特殊情況進行封裝,我們就得到了我們的縮放函式.注意一點的是使用縮放函式的時候,sx和sy如果不想讓其改變就設定為1,而不是0.
GAffineTransformMakeScale(CGFloat sx, CGFloat sy)
旋轉變換
條件 : tx=ty=0,a=cosɵ,b=sinɵ,c=-sinɵ,d=cosɵ
跟上面的兩種情況一樣,我們首先條件帶入我們的齊次座標裡面,看一下結果如何.
|cosɵ sinɵ 0|
[X,Y, 1] |-sinɵ cosɵ 0| = [Xcosɵ - Ysinɵ , Xsinɵ + Ycosɵ , 1] ;
|tx ty 1|
這個時候,ɵ就是旋轉的角度,逆時針為正,順時針為負。
那麼如果我們把這種特殊情況進行封裝,我們就得到了我們的縮放函式.
CGAffineTransformMakeRotation(CGFloat angle)
CGAffineTransform的使用
上面,我們已經對仿射變換有了大體的瞭解,知道了它的原理,那麼接下來我們就做一個簡單Demo.來看一下在Core Graphics框架中是如何使用仿射變換函式的.
首先還是建立SDView繼承與UIView類.
我們依然在drawInRect:
這個方法中進行我們的操作.我們在方法中先在圖形上下文中繪製一個矩形.程式碼如下.
//獲取圖形上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//建立路徑
CGPathRef path = CGPathCreateWithRect(CGRectMake(100, 100, 100, 100), nil);
//新增路徑
CGContextAddPath(context, path);
//設定顏色
CGContextSetRGBStrokeColor(context, 1.0, 0, 0, 1);
//繪製
CGContextDrawPath(context, kCGPathFillStroke);
//刪除路徑
CGPathRelease(path);
接下來我們直接在ViewController中新增SDView這個檢視.
#import "ViewController.h"
#import "SDView.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
SDView *view = [[SDView alloc]initWithFrame:self.view.frame];
view.backgroundColor = [UIColor whiteColor];
[self.view addSubview:view];
}
@end
效果如下.
上面繪製的矩形是沒有經過任何圖形變換的.接下來我們就在drawInRect:
這個方法中建立三種仿射變換.程式碼如下.
//建立平移變化結構體
CGAffineTransform translationAffineTransform = CGAffineTransformMakeTranslation(100, 0);
//建立縮放變化結構體
CGAffineTransform scaleAffineTransform = CGAffineTransformMakeScale(3, 0);
//建立縮放變化結構體
CGAffineTransform rotationAffineTransform = CGAffineTransformMakeRotation(M_PI_2);
緊接著,我們就把建立路徑這個程式碼替換成有仿射變換的路徑.(當然了,我們要把多餘的註釋掉嗷~~)
// //建立路徑
// CGPathRef path = CGPathCreateWithRect(CGRectMake(100, 100, 100, 100), nil);
//
//建立路徑(平移)
CGPathRef path = CGPathCreateWithRect(CGRectMake(100, 100, 100, 100), &translationAffineTransform);
//建立路徑(縮放)
CGPathRef path = CGPathCreateWithRect(CGRectMake(100, 100, 100, 100), &scaleAffineTransform);
//建立路徑(旋轉)
CGPathRef path = CGPathCreateWithRect(CGRectMake(100, 100, 100, 100), &rotationAffineTransform);
下面我們就看一下三種仿射變換的效果圖.
Core Graphics框架仿射變換就說這麼多了,後期,最後雙手奉上Demo.
-->仿射變換Demo傳送門?
相關文章
- 利用齊次座標進行二維座標轉換
- 齊次座標與投影幾何
- iOS 仿射變換(CGAffineTransform)iOSORM
- 仿射變換及其變換矩陣的理解矩陣
- pose座標變換
- 視覺化學習:CSS transform與仿射變換視覺化CSSORM
- Python pytorch 座標系變換與維度轉換PythonPyTorch
- 向量和矩陣的座標變換7矩陣
- Book of Shaders 02 - 矩陣:二維仿射變換練習矩陣
- ROS TF :使用 TF 設定機器人 釋出座標變換 使用座標變換 將感測器資料轉換為機器人座標系下ROS機器人
- OpenGL入門第三課--矩陣變換與座標系統矩陣
- svg06——svg中座標變換與順序的關係SVG
- 雷達座標變換及其相關運算
- 世界座標系到攝像機座標系的矩陣變換推導過程矩陣
- 向量和矩陣的座標變換(下標記法)7矩陣
- 地心地固座標系(ECEF)與站心座標系(ENU)的轉換
- Echarts:10-5-2:柱狀圖(座標軸刻度與標籤對齊)Echarts
- 帆軟層次座標
- 三維空間座標系變換-旋轉矩陣矩陣
- ArcGIS地圖投影與座標系轉換的方法地圖
- Qt - 座標系及轉換QT
- GPS座標轉換為BIM
- 線性變換和矩陣的橋樑篇2——像的座標標示矩陣
- 海康相機 畫素座標(px,py)到sdk ptz 座標轉換最後到onvif ptz座標
- 列主序儲存的4x4座標變換矩陣矩陣
- 仿射密碼密碼
- OpenCV計算機視覺學習(11)——影像空間幾何變換(影像縮放,影像旋轉,影像翻轉,影像平移,仿射變換,映象變換)OpenCV計算機視覺
- iOS開發UI篇--仿射變(CGAffineTransform)使用小結iOSUIORM
- iOS 頁面起始座標的變化iOS
- iOS開發中常見定位座標轉換iOS
- gps wgs4座標與高德gcj02座標互轉GC
- Proj4js wgs84與cgcs2000座標轉換示例JSGC
- 資料變換-歸一化與標準化
- 2024.10.3 揹包問題做完 ros實現烏龜跟隨(動態座標變換)ROS
- MathNet Ray3D座標系下轉換3D
- AUTOCAD——座標標註
- 座標系
- Go版本的各座標系互相轉換的工具Go
- ECharts圖座標軸文字換行問題處理Echarts