Apple Developer Connection
Member Login Log In | Not a Member? Contact ADC

< 前ページ次ページ > 目次を隠す

レイヤジオメトリと変換

この章では、レイヤのジオメトリの構成要素、要素どうしの関係、変換行列によりどのようにして複雑な視覚効果が生成されるかについて説明します。

目次:

レイヤ座標系
レイヤのジオメトリの指定
レイヤのジオメトリの変換


レイヤ座標系

レイヤの位置とサイズは、Quartzグラフィックス環境で使われるものと同じ座標系を使って表現されます。デフォルトでは、グラフィックス環境の原点(0.0,0.0)は左下角の位置であり、値は浮動小数点数として指定され、座標系単位の上と右に向かって増加します。座標系単位である単位正方形は、サイズが1.0×1.0の矩形です。

どのレイヤインスタンスもそれぞれ専用の座標系を定義、維持し、サブレイヤはすべてこの座標系を基準にして相対的に位置決めされ、描画が行われます。あるレイヤ座標系から別のレイヤ座標系へ、点、矩形、サイズを変換するメソッドが提供されています。あるレイヤの座標系は、サブレイヤも含め、そのレイヤのすべてのコンテンツの基本座標系と見なすことができます。

レイヤのジオメトリの指定

レイヤとレイヤツリーは、多くの点でCocoaのビューとビュー階層に似ていますが、レイヤのジオメトリは指定方法が異なり、たいていの場合はよりシンプルです。レイヤの変換行列も含め、レイヤのジオメトリのプロパティはすべて、暗黙的にも明示的にもアニメーション化できます。

図 1に、コンテキスト内でレイヤのジオメトリを指定するプロパティを示します。


図 1  CALayerジオメトリプロパティ

CALayer geometry properties

positionプロパティは、レイヤの位置をそのスーパーレイヤとの相対位置で指定するCGPointであり、スーパーレイヤの座標系で表現されます。

boundsプロパティは、レイヤのサイズ(bounds.size)と原点(bounds.origin)を指定するCGRectです。境界矩形の原点は、レイヤの描画メソッドをオーバーライドするときにグラフィックスコンテキストの原点として使われます。

レイヤには、positionプロパティ、boundsプロパティ、anchorPointプロパティ、およびtransformプロパティの役割を果たす暗黙のframeがあります。新しいフレーム矩形を設定すると、レイヤのpositionプロパティとboundsプロパティがそれに応じて変更されますが、フレーム自体は保存されません。新しいフレーム矩形が指定されても境界矩形の原点は変わらず、境界のサイズがフレームのサイズに設定されます。レイヤの位置は、アンカーポイントを基準に適切な位置に設定されます。frameプロパティ値を取得するときには、値はpositionプロパティ、boundsプロパティ、およびanchorPointプロパティを基準にして相対的に計算されます。

anchorPointプロパティは、レイヤの境界矩形内で位置座標に対応する位置を指定するCGPointです。アンカーポイントは、境界矩形が位置プロパティに対してどのように位置決めされるかを指定するほか、変換処理が適用される点の役割も果たします。アンカーポイントは、ユニット座標系で表します。すなわちレイヤの境界矩形の左下角は0.0,0.0、右上角は1.0,1.0となります。

レイヤのフレームを指定するときには、positionがアンカーポイントを基準にして相対的に設定されます。レイヤの位置を指定するときには、boundsがアンカーポイントを基準にして相対的に設定されます。

図 2に、アンカーポイントの3つの例を示します。


図 2  3つのanchorPoint値

Three anchorPoint values

anchorPointのデフォルト値は(0.5,0.5)であり、これはレイヤの境界矩形の中心点に相当します(図 2の点A)。点Bは、(0.0,0.5)に設定されたアンカーポイントの位置を示します。最後に点C(1.0,0.0)は、レイヤのpositionがフレームの右下角に設定されるように指定します。

frameプロパティ、boundsプロパティ、positionプロパティ、およびanchorPointプロパティの関係を、図 3に示します。


図 3  (0.5,0.5)のレイヤ原点

Layer Origin of (0.5,0.5)

この例では、anchorPointはレイヤの中心点に相当する(0.5,0.5)のデフォルト値に設定されています。レイヤのpositionは(100.0,100.0)に設定されており、boundsは矩形(0.0, 0.0, 120.0, 80.0)に設定されています。これにより、frameプロパティは(40.0, 60.0, 120.0, 80.0)として計算されます。

新しいレイヤを作成し、レイヤのframeプロパティだけを(40.0, 60.0, 120.0, 80.0)に設定すると、自動的にpositionプロパティは(100.0,100.0)に設定され、boundsプロパティは(0.0, 0.0, 120.0, 80.0)に設定されます。

図 4に、図 3のレイヤと同じframe矩形のあるレイヤを示します。しかし、この場合はレイヤのanchorPointは、レイヤの左下角に相当する(0.0,0.0)に設定されています。


図 4  (0.0,00.0)のレイヤ原点

Layer Origin of (0.0,0.0)

(40.0, 60.0, 120.0, 80.0)に設定されたフレームでは、boundsプロパティの値は同じですが、positionプロパティの値は変更されています。

Cocoaのビューとは異なるレイヤジオメトリのもう1つの側面は、レイヤの角を丸める半径を指定できることです。cornerRadiusプロパティは、コンテンツの描画、サブレイヤの切り取り、およびボーダーと影の描画の際にレイヤが使用する半径を指定します。

zPositionプロパティは、レイヤの位置のZ軸コンポーネントを指定します。zPositionは、レイヤの視覚上の位置を、その兄弟レイヤを基準にして相対的に設定することを意図しています。これはレイヤの兄弟の順番を指定するためではなく、サブレイヤ配列内でレイヤの順番を変えるために使われます。

レイヤのジオメトリの変換

レイヤのジオメトリが確定したら、行列変換を使ってこれを変換できます。Transformデータ構造体は、レイヤの回転、拡大縮小、オフセット、傾斜、レイヤへの透視変換の適用に使われる、3次元の同次変換(4×4行列のCGFloat値)を定義します。

2つのレイヤプロパティが変換行列を指定します。すなわち、transformsublayerTransformです。transformプロパティによって指定される行列は、レイヤとそのサブレイヤに対し、レイヤのanchorPointを基準にして相対的に適用されます。図 3は、レイヤがデフォルト値である(0.5,0.5)のanchorPointを使用しているときに、回転変換および拡大縮小変換によってどのように影響を受けるかを示しています。図 4は、(0.0,0.0)のanchorPointを使用した場合に、同じ変換行列によってレイヤがどのように影響を受けるかを示しています。sublayerTransformプロパティによって指定される行列は、レイヤ自身ではなく、レイヤのサブレイヤに対してのみ適用されます。

CATransform3Dデータ構造体は、次のいずれかの方法で作成および変更できます。

定数CATransform3DIdentityは同一行列、すなわち拡大縮小、回転、傾斜、透視変換の適用を行わない行列です。同一行列をレイヤに適用すると、レイヤはデフォルトのジオメトリで表示されます。

変換関数

Core Animationで使用可能な変換関数は、行列を操作します。これらの関数(表 1に示す)を使い、レイヤまたはそのサブレイヤに適用する行列をtransformメソッドとsublayerTransformメソッドでそれぞれ作成できます。変換関数には、CATransform3Dデータ構造体を操作するものと、これを返すものがあります。これにより、再利用しやすい、シンプルな変換や複雑な変換を作成できます。

表 1  平行移動、回転、拡大縮小のためのCATransform3D変換関数

関数

用途

CATransform3DMakeTranslation

'(tx, ty, tz)'の平行移動を行う変換を返します:t' = [1 0 0 0; 0 1 0 0; 0 0 1 0; tx ty tz 1]

CATransform3DTranslate

't'を'(tx, ty, tz)'だけ平行移動して、その結果を返します: * t' = translate(tx, ty, tz) * t

CATransform3DMakeScale

`(sx, sy, sz)'の拡大縮小を行う変換を返します:* t' = [sx 0 0 0; 0 sy 0 0; 0 0 sz 0; 0 0 0 1]

CATransform3DScale

't'を'(sx, sy, sz)'だけ拡大縮小し、その結果を返します:* t' = scale(sx, sy, sz) * t

CATransform3DMakeRotation

ベクトル'(x, y, z)'を中心にしてラジアン'angle'分の回転をする変換を返します。ベクトルの長さがゼロの場合は同一変換が返されます。

CATransform3DRotate

ベクトル'(x, y, z)'を中心にして't'をラジアン'angle'だけ回転し、その結果を返します:t' = rotation(angle, x, y, z) * t

回転角度は、度数ではなくラジアンで指定されます。次の関数を使って、ラジアンと度数の間を変換できます。

CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
CGFloat RadiansToDegrees(CGFloat radians) {return radians / M_PI / 180;};

Core Animationは、行列の反転を行う変換関数CATransform3DInvertを提供しています。逆変換は一般に、変換済みのオブジェクト内の点を逆変換するために使います。逆変換は行列によって変換された値の元の値を取得する場合に便利です。つまり、行列を逆変換し、得られた値に逆変換行列を乗じた結果が元の値です。

また、CATransform3D行列をCGAffineTransform行列で表現できる場合は、そのようにCATransform3D行列を変換する関数も提供されています。

表 2  CGAffineTransform変換のためのCATransform3D変換関数

関数

用途

CATransform3DMakeAffineTransform

渡されたアファイン変換と同じ効果のCATransform3Dを返します。

CATransform3DIsAffine

渡されたCATransform3Dをアファイン変換で正確に表現できる場合は、YESを返します。

CATransform3DGetAffineTransform

渡されたCATransform3Dによって表現されたアファイン変換を返します。

変換行列と同一行列、または別の変換行列との同等性の比較を行う関数が提供されています。

表 3  同等性のテストのためのCATransform3D変換関数

関数

用途

CATransform3DIsIdentity

変換が同一変換であれば、YESを返します。

CATransform3DEqualToTransform

2つの変換がまったく同一であれば、YESを返します。

変換データ構造体の変更

他のデータ構造体の場合と同様に、CATransform3Dデータ構造体の任意のメンバの値を変更できます。リスト 1にはCATransform3Dデータ構造体の定義が含まれており、構造体メンバは対応する行列位置に表示されます。

リスト 1  CATransform3D構造体

 
struct CATransform3D
{
  CGFloat m11, m12, m13, m14;
  CGFloat m21, m22, m23, m24;
  CGFloat m31, m32, m33, m34;
  CGFloat m41, m42, m43, m44;
};
 
typedef struct CATransform3D CATransform3D;

リスト 2の例は、CATransform3Dを透視変換として構成する方法を示しています。

リスト 2  CATransform3Dデータ構造体の直接的な変更

 t = CATransform3DIdentity;
// zDistanceの値は変換の精度に影響する。
zDistance = 850;
t.m34 = 1.0 / -zDistance;

キーパスを使った変換の変更

Core Animationでは、キー値コーディングプロトコルが拡張されており、キーパスを通じてレイヤのCATransform3D行列の一般的な値の取得と設定ができるようになっています。表 4に、キー値コーディングとキー値監視に準拠しているレイヤのtransformプロパティとsublayerTransformプロパティのキーパスについて説明します。

表 4  CATransform3Dキーパス

フィールドキーパス

説明

rotation.x

ラジアン単位によるX軸での回転。

rotation.y

ラジアン単位によるY軸での回転。

rotation.z

ラジアン単位によるZ軸での回転。

rotation

ラジアン単位によるZ軸での回転。これは、rotation.zフィールドを設定することと同じです。

scale.x

X軸の拡大縮小倍率。

scale.y

Y軸の拡大縮小倍率。

scale.z

Z軸の拡大縮小倍率。

scale

3つの拡大縮小倍率すべての平均。

translation.x

X軸での平行移動。

translation.y

Y軸での平行移動。

translation.z

Z軸での平行移動。

translation

XおよびY軸での平行移動。値はNSSizeまたはCGSizeです。

Objective-C 2.0のプロパティを使って構造体のフィールドキーパスを指定することはできません。次のような指定はできません。

myLayer.transform.rotation.x=0;

代わりに、次に示すようにsetValue:forKeyPath:またはvalueForKeyPath:を使う必要があります。

[myLayer setValue:[NSNumber numberWithInt:0] forKeyPath:@"transform.rotation.x"];


< 前ページ次ページ > 目次を隠す


Last updated: 2007-12-06




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.
Get information on Apple products.
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Copyright © 2007 Apple Inc.
All rights reserved. | Terms of use | Privacy Notice