核心動(dòng)畫(一)

核心動(dòng)畫知識(shí)導(dǎo)入

CoreAnimation框架是基于OpenGL ES 手機(jī)端/OpenGL PC端(iOS13開始為Metal)與CoreGraphics圖像處理框架的一個(gè)跨平臺(tái)的框架钞啸。

了解CoreAnimation
核心動(dòng)畫
  • CoreAnimation的封裝核心就是去簡(jiǎn)化OpenGL圖形處理树枫,原因是OpenGL的學(xué)習(xí)成本是非常高的肩祥;CoreAnimation也可以用作Mac OS開發(fā)
  • Core Graphics 核心繪圖
  • Graphics Hardware 圖形加速硬件戒悠,這個(gè)圖形硬件就是GPU芯片逆趋,GPU專門用來做計(jì)算锥咸,GPU并不是顯卡靶溜,而是顯卡需要GPU
  • iOS 13之后OpenGL更新為Metal匾乓,Metal只針對(duì)iOSMac OS系統(tǒng);而OpenGL ES是可以針對(duì)整個(gè)嵌入式環(huán)境(安卓鳄厌、黑莓等都可以使用)
GPUCPU的區(qū)別

CPU: 中央處理器(英文Central Processing Unit)是一臺(tái)計(jì)算機(jī)的運(yùn)算核心和控制核心荞胡;其功能主要是解釋計(jì)算機(jī)指令以及處理計(jì)算機(jī)軟件中的數(shù)據(jù)
GPU:圖形處理器(英文Graphic Processing Unit)是一個(gè)專門的圖形核心處理器了嚎;GPU是顯卡的大腦泪漂,決定了該顯卡的檔次和大部分性能,同時(shí)也是2D顯卡3D顯卡的區(qū)別依據(jù)歪泳;2D顯示芯片在處理3D圖像和特效時(shí)主要依賴CPU的處理能力萝勤,稱為軟加速;3D顯示芯片是將三維圖像和特效處理功能集中在顯示芯片內(nèi)呐伞,也即所謂的硬件加速敌卓。

主要區(qū)別如下:

  • CPU需要很強(qiáng)的通用性來處理各種不同的數(shù)據(jù)類型,同時(shí)又要邏輯判斷又會(huì)引入大量的分支跳轉(zhuǎn)中斷的處理伶氢,這些都使得CPU的內(nèi)部結(jié)構(gòu)異常復(fù)雜趟径;而GPU面對(duì)的則是類型高度統(tǒng)一的相互無(wú)依賴的大規(guī)模數(shù)據(jù)和不需要被打斷純凈的計(jì)算環(huán)境
  • GPU采用了數(shù)量眾多的計(jì)算單元超長(zhǎng)的流水線癣防,但只有非常簡(jiǎn)單的控制邏輯并省去了Cache蜗巧,而CPU不僅被Cache占據(jù)了大量空間,而且還有有復(fù)雜的控制邏輯和諸多優(yōu)化電路劣砍,相比之下計(jì)算能力只是CPU很小的一部分惧蛹。
核心動(dòng)畫的優(yōu)點(diǎn)
  • 簡(jiǎn)單易用的高性能混合編程模型
  • 用類似于UIView一樣,使?圖層來創(chuàng)建復(fù)雜的編程接口刑枝,更加高效的使用
  • 輕量化的數(shù)據(jù)結(jié)構(gòu)香嗓,它可以同時(shí)顯示讓上百個(gè)圖層產(chǎn)?動(dòng)畫效果
  • 一套?常簡(jiǎn)單的動(dòng)畫接口,能讓動(dòng)畫運(yùn)?在獨(dú)立的線程中装畅,并可以獨(dú)?于主線程之外
  • 一旦動(dòng)畫配置完成并啟動(dòng)靠娱,核?動(dòng)畫就能獨(dú)立并完全控制相應(yīng)的動(dòng)畫幀
  • 提?應(yīng)用性能,應(yīng)?程序只有當(dāng)發(fā)生改變的時(shí)候才會(huì)重繪內(nèi)容掠兄,使用Core Animation 可以不使?其他圖形API像云,例如OpenGL來獲取高效的動(dòng)畫性能.
  • 靈活的布局管理模型锌雀,允許圖層相對(duì)同級(jí)圖層的關(guān)系來設(shè)置屬性的位置和?小

核心動(dòng)畫圖層樹結(jié)構(gòu)

CoreAnimation核心動(dòng)畫的結(jié)構(gòu)圖
CoreAnimation分類

CAAnimation是所有動(dòng)畫對(duì)象的父類(抽象類,虛類)迅诬,實(shí)現(xiàn)CAMediaTiming協(xié)議腋逆,負(fù)責(zé)控制動(dòng)畫的時(shí)間、速度和時(shí)間曲線等等侈贷,是一個(gè)抽象類惩歉。

核心動(dòng)畫類中可以直接使用的類有五個(gè),其中CAAnimation俏蛮、CAPropertyAnimation是抽象類撑蚌,不能直接使用。

  • CAAnimationGroup: 動(dòng)畫組搏屑,可以將很多種動(dòng)畫合并到一起争涌,組成動(dòng)畫效果
  • CATransition: 轉(zhuǎn)場(chǎng)動(dòng)畫效果
  • CAKeyframeAnimation: 關(guān)鍵幀動(dòng)畫效果;values: 一個(gè)NSArray對(duì)象辣恋;里面的元素稱為關(guān)鍵幀(keyframe)亮垫,動(dòng)畫對(duì)象會(huì)在指定的時(shí)間(duration)內(nèi),依次顯示values數(shù)組中的每一個(gè)關(guān)鍵幀抑党;簡(jiǎn)單理解為包警,很多動(dòng)畫幀執(zhí)行
  • CABasicAnimation: 基礎(chǔ)動(dòng)畫,簡(jiǎn)單常見的動(dòng)畫效果
  • CASpringAnimation: iOS9.0之后新增的彈簧效果動(dòng)畫底靠,是CABasicAnimation的子類
CALayerUIView的區(qū)別
  • CALayer:繼承于NSObject,所以不具備響應(yīng)不能處理用戶交互特铝,負(fù)責(zé)繪制暑中、渲染圖形
  • UIView: 繼承于UIResponder,所以可以進(jìn)行事件響應(yīng)鲫剿,屬性CALayer負(fù)責(zé)圖形繪制與渲染鳄逾;UIViewCALayer的delegate,可以實(shí)現(xiàn)一些簡(jiǎn)單的CALayer的方法灵莲,但要實(shí)現(xiàn)稍微復(fù)雜些的動(dòng)畫效果雕凹,就需要借助CALayer,如:陰影政冻,圓角枚抵,帶顏色的邊框3D變換明场、非矩形范圍汽摹、透明遮罩多級(jí)非線性動(dòng)畫等苦锨,這也就是開發(fā)者為什么要使用CALayer的原因
  • UIView是用來管理CALayer逼泣,CALayer才是用來展示

疑問:蘋果為什么要拆分成CALayerUIView兩個(gè)類呢趴泌?
CoreAnimation是iOS與Mac OS共用的框架,而iOS與Mac OX兩者的用戶交互方式是不同的拉庶,iOS是通過手勢(shì)觸摸嗜憔,Mac OX是通過鍵盤鼠標(biāo);為了兼容兩者氏仗,單獨(dú)把CALayer拆出來只用來繪制渲染圖形

CALayerUIView的關(guān)系
CALayer與UIView的關(guān)系

每一個(gè)UIView上面都會(huì)有一個(gè)CALayer作為它的實(shí)例圖層屬性痹筛;我們添加的動(dòng)畫實(shí)際上是針對(duì)CALayer來做。

CALayer的樹級(jí)關(guān)系一
CALayer的樹級(jí)關(guān)系二

Layer Tree圖層樹(模型數(shù))主要是設(shè)置一些屬性

  • 模型樹( layer tree):程序中接觸最頻繁廓鞠,模型樹的對(duì)象是模型對(duì)象帚稠,儲(chǔ)存著動(dòng)畫的目標(biāo)值;當(dāng)你修改layer的屬性時(shí)床佳,便是通過模型樹上的對(duì)象
  • 呈現(xiàn)樹(presentation tree):包含正在運(yùn)行中的動(dòng)畫的動(dòng)態(tài)值滋早,與模型樹不同,呈現(xiàn)樹始終存儲(chǔ)著layer在屏幕當(dāng)前的狀態(tài)值砌们,呈現(xiàn)樹無(wú)法修改杆麸,只讀;可以通過讀取當(dāng)前值浪感,來做一些其他處理
  • 渲染樹(render tree):執(zhí)行實(shí)際的動(dòng)畫昔头,為CoreAnimation私有

小結(jié):動(dòng)畫的三個(gè)動(dòng)作創(chuàng)建執(zhí)行動(dòng)畫的CALayer創(chuàng)建動(dòng)畫影兽、添加動(dòng)畫

CALayer常用屬性詳解

動(dòng)畫案例準(zhǔn)備工作:新建空工程CoreAnimation揭斧,在Main.storyboard文件拖入一個(gè)UIView,背景色配置成紅色并進(jìn)行關(guān)連峻堰,命名為redView

動(dòng)畫案例一
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *redView;
@property (nonatomic,strong) CALayer *layer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 新建layer讹开,并添加到self.view.layer上
    CALayer *layer = [CALayer layer];
    layer.frame = CGRectMake(100, 100, 100, 100);
    layer.backgroundColor = [UIColor greenColor].CGColor;
    _layer = layer;
    [self.view.layer addSublayer:layer];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    CABasicAnimation *animation = [CABasicAnimation animation];
    // 修改動(dòng)畫y的位置到600
    animation.keyPath = @"position.y";
    animation.toValue = @600;
    animation.duration = 1;
    [_redView.layer addAnimation:animation forKey:nil];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

運(yùn)行工程并點(diǎn)擊屏幕,我們會(huì)發(fā)現(xiàn)動(dòng)畫執(zhí)行完畢后捐名,又回到了初始位置旦万,為什么會(huì)這樣?
其實(shí)在執(zhí)行動(dòng)畫的過程中會(huì)有兩個(gè)圖層:layer層presentation層镶蹋,真正移動(dòng)的是presentation層成艘;動(dòng)畫開始時(shí)會(huì)先把layer層隱藏,讓presentation層做動(dòng)畫贺归;動(dòng)畫結(jié)束后presentation層就會(huì)移除淆两,layer層再出現(xiàn);原因是視圖的layer層根本沒有發(fā)生變化牧氮,動(dòng)畫結(jié)束就會(huì)恢復(fù)到原來的狀態(tài)琼腔。

解決辦法:設(shè)置animation的兩個(gè)屬性

//解決動(dòng)畫恢復(fù)到初始位置
//當(dāng)動(dòng)畫完成后,不把presentation層從render樹中移除(默認(rèn)是移除的)
animation.removedOnCompletion = NO;
//當(dāng)動(dòng)畫結(jié)束后踱葛,把layer層狀態(tài)同步到presentation層丹莲;此時(shí)_redView的frame才會(huì)發(fā)生變化
animation.fillMode = kCAFillModeForwards;

CABasicAnimation相當(dāng)于是一個(gè)數(shù)據(jù)模型光坝,把該數(shù)據(jù)模型綁定到layer上面。

CABasicAnimation動(dòng)畫的fillMode屬性介紹
  • kCAFillModeForwards:動(dòng)畫結(jié)束后甥材,layer會(huì)一直保持動(dòng)畫最后的狀態(tài)
  • kCAFillModeBackwards:動(dòng)畫開始前盯另,只要將動(dòng)畫加入一個(gè)layerlayer便立即進(jìn)入動(dòng)畫的初始狀態(tài)并等待動(dòng)畫開始
  • kCAFillModeBothkCAFillModeForwardskCAFillModeBackwards兩者的結(jié)合洲赵,開始前保持動(dòng)畫初始狀態(tài)鸳惯,結(jié)束后保持動(dòng)畫的最后狀態(tài)
  • kCAFillModeRemoved:默認(rèn)屬性
動(dòng)畫案例二:隱式動(dòng)畫

疑問:上面紅色圖層動(dòng)畫結(jié)束恢復(fù)到原來的狀態(tài),恢復(fù)的過程給人的感覺是回彈動(dòng)畫叠萍,這就是隱式動(dòng)畫?

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    _layer.backgroundColor = [UIColor orangeColor].CGColor;
}

我們沒有給_layer層添加動(dòng)畫芝发,但是點(diǎn)擊頁(yè)面_layer層由綠色變成橙色的過程,有一種動(dòng)畫的效果苛谷,這就是隱式動(dòng)畫辅鲸;隱式動(dòng)畫是由CoreAnimation框架幫我們做的,其默認(rèn)動(dòng)畫時(shí)長(zhǎng)是0.25秒腹殿,通過runloop來執(zhí)行独悴。上面添加的CABasicAnimation屬于顯式動(dòng)畫

動(dòng)畫案例三:修改隱式動(dòng)畫

如何修改系統(tǒng)的隱式動(dòng)畫呢锣尉?

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //begin a new transaction
    [CATransaction begin];
    //設(shè)置隱式動(dòng)畫的時(shí)長(zhǎng)
    [CATransaction setAnimationDuration:2.0];
    _layer.backgroundColor = [UIColor orangeColor].CGColor;
    //動(dòng)畫執(zhí)行完成的回調(diào)
    [CATransaction setCompletionBlock:^{
        //添加轉(zhuǎn)場(chǎng)動(dòng)畫
        //rotate the layer 90 degrees
        CGAffineTransform transform = self.layer.affineTransform;
        transform = CGAffineTransformRotate(transform, M_PI_2);
        self.layer.affineTransform = transform;

    }];
    [CATransaction commit];
}

CATransaction類沒有屬性刻炒,也沒有實(shí)例方法;不能通過alloc init去創(chuàng)建自沧,只能通過begin坟奥、commit壓棧出棧的方式來管理。

動(dòng)畫案例四:CALayer常用屬性 - Contents
- (void)viewDidLoad {
    [super viewDidLoad];
    //除了UIImageView 能夠顯示圖片,layer也可以加載圖片
    UIImage *image = [UIImage imageNamed:@"test.png"];
    //不用CGImage的話暂幼,圖片加載不出來
    self.view.layer.contents = (__bridge id)(image.CGImage);
    //填充方式
    self.view.contentMode = UIViewContentModeScaleAspectFit;
    self.view.layer.contentsGravity = kCAGravityResizeAspect;
}

Contents屬性是id類型筏勒,原因是在Mac OS系統(tǒng)上Contents屬性對(duì)CGImageNSImage都會(huì)起作用,image.CGImage實(shí)際上賦值的是CGImageRef類型旺嬉,CGImageRef指向的是CGImage結(jié)構(gòu),需要進(jìn)行橋接處理厨埋,開發(fā)中如果需要設(shè)置背景圖可以使用layer邪媳;Contents是id類型就可以直接在layercontents上面加載一張圖片。

  • CALayer常用屬性 - contentsScale
self.view.layer.contentsScale = [[UIScreen mainScreen] scale];

當(dāng)用代碼設(shè)置contents圖片時(shí)荡陷,要?動(dòng)設(shè)置圖層的contentsScale屬性雨效,避免Retina屏幕顯示錯(cuò)誤。

  • CALayer常用屬性 - makeToBounds
    makeToBounds屬性類似于UIView中的clipsToBounds屬性废赞,含義:是否顯示超出邊界的內(nèi)容徽龟?

  • CALayer常用屬性 - contentsRect

  1. contentsRect不是按點(diǎn)來計(jì)算的,而是按照單位坐標(biāo)唉地;
  2. OpenGL的坐標(biāo)系橫向是從-1到1据悔,縱向從1到-1的過程传透,center坐標(biāo)就是{0, 0},而手機(jī)都是長(zhǎng)方形的极颓,所以OpenGL會(huì)把單位坐標(biāo)系轉(zhuǎn)換為設(shè)備坐標(biāo)系朱盐,不同設(shè)備有不同的坐標(biāo);
點(diǎn)- 像素 - 單位區(qū)分
contentsRect屬性

contentsRectcontentsGravity屬性要靈活很多菠隆,contentsGravity屬性只能展示圖片固定的位置與大小兵琳,而contentsRect可以展示圖片的任意內(nèi)容(只要把單位坐標(biāo)計(jì)算好即可);如果contentsGravity不能滿足我們的需求時(shí)骇径,可以使用contentsRect屬性躯肌。

CALayer中HitTest屬性的實(shí)際使用

下面我們來了解一下UIViewCALayer圖層幾何

圖層幾何

frame是相對(duì)于父視圖的坐標(biāo),bounds是從視圖自身出發(fā)即內(nèi)部坐標(biāo)破衔,centerposition相當(dāng)于父視圖上面的一個(gè)錨點(diǎn)

錨點(diǎn)

錨點(diǎn)就是視圖中的center屬性position屬性清女,實(shí)際上就是一個(gè)坐標(biāo),錨點(diǎn)anchorPointlayer的屬性(即position)运敢。

  • CALayer常用屬性 - ZPosition
ZPosition

手機(jī)開發(fā)是基于二維平面的校仑,并不是一個(gè)優(yōu)秀的三維圖形顯示載體,但是手機(jī)中會(huì)出現(xiàn)一些立體的粒子效果传惠,于是CALayer就提供了一個(gè)屬性ZPosition迄沫,也就意味著CALayer是三維的;OpenGLMetal默認(rèn)是一個(gè)3D圖形api卦方,默認(rèn)坐標(biāo)系是三維坐標(biāo)系羊瘩,在描述平面圖形的時(shí)候,z坐標(biāo)是0盼砍;核心動(dòng)畫把z坐標(biāo)單獨(dú)摘出來就是ZPosition尘吗;呈現(xiàn)粒子的時(shí)候就必須要用到ZPosition

動(dòng)畫案例準(zhǔn)備工作:新建空工程CoreAnimation2浇坐,在Main.storyboard文件拖入兩個(gè)UIView睬捶,背景色配置成橙色紅色并進(jìn)行關(guān)連,命名為view1view2近刘,兩個(gè)view的層級(jí)關(guān)系如下

兩個(gè)view的層級(jí)
// ViewController.h文件
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view1.layer.zPosition = 1.0;
}

運(yùn)行工程擒贸,我們發(fā)現(xiàn)橙色view出現(xiàn)在了紅色view上面,原因是什么呢觉渴?
在平面圖形上面z軸默認(rèn)值是0介劫,這里把橙色viewz軸值設(shè)置為1,就意味著把橙色view放在了上面案淋;修改了zPosition屬性的值座韵,就更改了深度緩沖區(qū)-深度測(cè)試,這里主要與深度緩沖區(qū)有關(guān)踢京,本質(zhì)并不是修改圖層的層級(jí)關(guān)系誉碴。

  • CALayer常用屬性 -Hit Testing

動(dòng)畫案例準(zhǔn)備工作:新建空工程CoreAnimation3宦棺,在Main.storyboard文件拖入一個(gè)UIView,背景色配置成紅色并進(jìn)行關(guān)連翔烁,命名為layerView渺氧,如下圖所示

CoreAnimation3工程
#import "ViewController.h"

@interface ViewController ()
@property (strong, nonatomic) UIView *layerView;
@property (strong,nonatomic) CALayer *blueLayer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //1.Create sublayer
    self.blueLayer = [CALayer layer];
    self.blueLayer.frame = CGRectMake(0, 0, 100, 100);
    self.blueLayer.backgroundColor = [UIColor blueColor].CGColor;
    [self.layerView.layer addSublayer:self.blueLayer];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //1.get touchu position relative to main view(獲取相對(duì)于主視圖的觸摸位置)
    CGPoint point = [[touches anyObject]locationInView:self.view];
    //2.get touched layer
    CALayer *layer = [self.layerView.layer hitTest:point];
    //3.get layer using using hitTest
    if(layer == self.blueLayer)
    {           
        NSLog(@"Inside Blue layer");
    } else if (layer == self.layerView.layer) {
        NSLog(@"Inside Red layer");
    }
}

@end

// 運(yùn)行工程,查看打印日志蹬屹,成功獲取點(diǎn)擊的layer層
2022-09-23 22:25:56.044062+0800 CoreAnimation3[22331:14483795] Inside Blue layer
2022-09-23 22:25:59.342807+0800 CoreAnimation3[22331:14483795] Inside Red layer

CALayer不能響應(yīng)事件侣背,但是CALayerHit Testing屬性能夠獲取到點(diǎn)擊的圖層。

hitTest方法介紹
// point : 在接收器的局部坐標(biāo)系(界)中指定的點(diǎn)
// event : 系統(tǒng)保證調(diào)用此方法的事件慨默。如果從事件處理代碼外部調(diào)用此方法贩耐,則可以指定nil
// returnValue : 視圖對(duì)象是當(dāng)前視圖和包含點(diǎn)的最遠(yuǎn)的后代。
//               如果點(diǎn)完全位于接收方的視圖層次結(jié)構(gòu)之外厦取,則返回nil
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event

不止CALayer中有hitTest方法潮太,UIView中同樣有hitTest方法;UIView中該方法的作用:在視圖的層次結(jié)構(gòu)中尋找一個(gè)最合適的view來響應(yīng)觸摸事件虾攻;該方法會(huì)被系統(tǒng)調(diào)用铡买,調(diào)用時(shí)如果返回nil,即事件被丟棄霎箍,否則返回最合適的view來響應(yīng)事件奇钞。

  • Hit Test調(diào)用順序
touch -> UIApplication -> UIWindow -> UIViewController.view -> subViews -> ....-> 合適的view
  • 事件的傳遞順序,與Hit Test調(diào)用順序剛好相反
 view -> superView ...- > UIViewController.view -> UIViewController ->UIWindow -> UIApplication -> 丟棄事件

說明:

  1. 首先由view來嘗試處理事件漂坏,如果處理不了景埃,事件將被傳遞到父視圖superView
  2. superView也嘗試處理事件,如果處理不了顶别,繼續(xù)傳遞給它的父視圖UIViewController.view
  3. UIViewController.view嘗試處理事件谷徙,如果處理不了,把該事件傳遞給UIViewController
  4. UIViewController嘗試處理事件驯绎,如果處理不了完慧,把事件傳遞給UIWindow
  5. 主窗口UIWindow嘗試來處理事件, 如果處理不了剩失,將傳遞給應(yīng)用單例UIApplication
  6. 如果UIApplication也處理不了骗随,該事件將被丟棄
UIViewHit Test底層實(shí)現(xiàn)思路

常見的hitTest不實(shí)現(xiàn)的四種情況(即view不響應(yīng)事件情況)

  • view.userInteractionEnabled = NO;
  • view.hidden = YES;
  • view.alpha < 0.05;
  • view 超出 superview 的 bounds;
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    //1.是否響應(yīng)事件的必然性條件
    if (self.userInteractionEnabled == NO || self.alpha < 0.05 || self.hidden == YES)
    {
        return nil;
    }
    
    //2.touch的point在self.bounds內(nèi)
    if ([self pointInside:point withEvent:event])
    {
        for (UIView *subView in self.subviews)
        {
            //進(jìn)行坐標(biāo)轉(zhuǎn)化
            CGPoint coverPoint = [subView convertPoint:point fromView:self];
            // 調(diào)用子視圖的 hitTest 重復(fù)上面的步驟。找到了赴叹,返回hitTestview ,沒找到返回有自身處理
            UIView *hitTestView = [subView hitTest:coverPoint withEvent:event];
            if (hitTestView)
            {
                return hitTestView;
            }
        }
        return self;
    }
    return nil;
}

Hit Testing應(yīng)?場(chǎng)景-?視圖超出?視圖范圍,點(diǎn)擊沒有響應(yīng)指蚜;如果需求是讓超出父視圖的范圍也能點(diǎn)擊乞巧,代碼實(shí)現(xiàn)如下

?視圖超出?視圖范圍
實(shí)現(xiàn)思路

仿射變換數(shù)學(xué)原理講解

圖層變換
  • 剛體變換:只有物體的位置(平移變換)和朝向(旋轉(zhuǎn)變換)發(fā)生改變,而形狀不變摊鸡;剛性變換是最一般的變換绽媒。
  • 仿射變換:仿射變換具有兩個(gè)旋轉(zhuǎn)因子兩個(gè)縮放因子蚕冬,因此具有6個(gè)自由度。不具有保角性和保持距離比的性質(zhì)是辕,但是原圖平行線變換后仍然是平行線囤热。仿射變換主要包括平移變換旋轉(zhuǎn)變換获三、縮放變換(也叫尺度變換)旁蔼、傾斜變換(也叫錯(cuò)切變換、剪切變換疙教、偏移變換)棺聊、翻轉(zhuǎn)變換,有六個(gè)自由度贞谓。
  • 投影變換:是最一般的線性變換限佩,有8個(gè)自由度;射影變換保持重合關(guān)系和交比不變裸弦。但不會(huì)保持平行性祟同。即它會(huì)使得仿射變換產(chǎn)生非線性效應(yīng)
仿射變換
投影的兩種類型

對(duì)于復(fù)雜的立體圖形理疙,我們要想平移是非常困難的晕城;但是通過仿射變換,我們就可以很容易的實(shí)現(xiàn)沪斟,可以對(duì)立體圖形的任意頂點(diǎn)進(jìn)行平移广辰,實(shí)現(xiàn)代碼如下圖所示:

對(duì)立體圖形進(jìn)行平移

核心動(dòng)畫官方文檔地址

下面我們介紹官方文檔中的幾個(gè)矩陣
矩陣

上圖展現(xiàn)了常見的transformations的矩陣配置;任何乘以identity矩陣的coordinate將不會(huì)變化主之,當(dāng)乘以其他矩陣時(shí)择吊,coordinate的變化和矩陣每個(gè)分量都有關(guān);例如槽奕,沿著X軸平移几睛,我們需要提供非零的 tx 分量并讓tytz為0;對(duì)于旋轉(zhuǎn)操作粤攒,我們應(yīng)該提供合適的 sinecosine 值所森。

  • Identity:?jiǎn)卧仃?/li>
  • Translate:平移
  • Scale:縮放
  • Rotate around X axis:圍繞X軸旋轉(zhuǎn),X值不變夯接;這里的四維原因是OpenGL ES/Metal中描述頂點(diǎn)除了圍繞X焕济、YZ軸盔几,還有一個(gè)W縮放因子晴弃。
  • Rotate around Y axis:圍繞Y軸旋轉(zhuǎn),Y值不變
  • Rotate around Z axis:圍繞Z軸旋轉(zhuǎn),Z值不變
圍繞任意軸旋轉(zhuǎn)

圍繞任意軸旋轉(zhuǎn)中參數(shù)n表示向量(x,y,z)上鞠,第二個(gè)參數(shù)表示角度际邻。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市芍阎,隨后出現(xiàn)的幾起案子世曾,更是在濱河造成了極大的恐慌,老刑警劉巖谴咸,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轮听,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡寿冕,警方通過查閱死者的電腦和手機(jī)蕊程,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來驼唱,“玉大人藻茂,你說我怎么就攤上這事∶悼遥” “怎么了辨赐?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)京办。 經(jīng)常有香客問我掀序,道長(zhǎng),這世上最難降的妖魔是什么惭婿? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任不恭,我火速辦了婚禮,結(jié)果婚禮上财饥,老公的妹妹穿的比我還像新娘换吧。我一直安慰自己,他們只是感情好钥星,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布沾瓦。 她就那樣靜靜地躺著,像睡著了一般谦炒。 火紅的嫁衣襯著肌膚如雪贯莺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天宁改,我揣著相機(jī)與錄音缕探,去河邊找鬼瀑晒。 笑死走趋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的或链。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼鲸沮,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了锅论?” 一聲冷哼從身側(cè)響起讼溺,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎最易,沒想到半個(gè)月后怒坯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡藻懒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年剔猿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嬉荆。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡归敬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鄙早,到底是詐尸還是另有隱情汪茧,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布限番,位于F島的核電站舱污,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏弥虐。R本人自食惡果不足惜扩灯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望霜瘪。 院中可真熱鬧珠插,春花似錦、人聲如沸粥庄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)惜互。三九已至布讹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間训堆,已是汗流浹背描验。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留坑鱼,地道東北人膘流。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓絮缅,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親呼股。 傳聞我的和親對(duì)象是個(gè)殘疾皇子耕魄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • [toc] 前言 Core Animation提供了一種通用系統(tǒng),可對(duì)應(yīng)用程序的視圖和其他視覺元素進(jìn)行動(dòng)畫處理彭谁。C...
    清風(fēng)烈酒2157閱讀 304評(píng)論 0 1
  • iOS核心動(dòng)畫 核心動(dòng)畫框架 CoreAnimation框架是基于OpenGL與CoreGraphics圖像處理框...
    小白PK大牛閱讀 363評(píng)論 0 0
  • 本文是要點(diǎn)型筆記吸奴,建議先閱讀以下參考內(nèi)容后再閱讀,完成知識(shí)體系的構(gòu)建:[1] View Programming ...
    SvenLearn閱讀 2,964評(píng)論 2 43
  • 最近買了幾本書缠局,接下來會(huì)陸續(xù)寫寫筆記则奥,把書中干貨分享出來 筆記主要總結(jié)了書中講了什么內(nèi)容,希望讀者讀完后遇到相應(yīng)的...
    搬磚人666閱讀 1,954評(píng)論 0 6
  • 基礎(chǔ) 核心動(dòng)畫是 iOS 和 MacOS 上的圖形渲染和動(dòng)畫基礎(chǔ)結(jié)構(gòu)狭园,用于為應(yīng)用的視圖和其他視覺元素設(shè)置動(dòng)畫读处。 核...
    davon閱讀 1,886評(píng)論 0 8