アットウィキロゴ

playdate.geometry.affineTransform

playdate.geometry.affineTransform は、2D のアフィン変換行列を表す型です。
アフィン変換



概要

playdate.geometry.affineTransform は、2D のアフィン変換行列を表す型です。
用途としては主に次です。
  • 平行移動
  • 回転
  • 拡大縮小
  • skew(せん断)
  • 複数変換の合成
  • point / polygon / lineSegment / rect への変換適用
内部表現は典型的な 2D アフィン変換の 6 要素:
  1. m11
  2. m12
  3. m21
  4. m22
  5. tx
  6. ty
を持つ形式です。
これは通常、2D 点 (x, y) を
  • x' = m11*x + m21*y + tx
  • y' = m12*x + m22*y + ty
のように変換するタイプの行列です。

また、公開プロパティは基本的にないため、affineTransform は、中身を直接いじる型というより、メソッド経由で操作する型 と見てよいです。

コンストラクタ

new()
単位変換(identity transform)を返します
戻り値
  • _AffineTransform
意味
何も変換しない変換です。
  • 回転なし
  • 拡大縮小なし
  • skew なし
  • 平行移動なし
実質的なイメージ
  • m11 = 1
  • m22 = 1
  • それ以外は 0
用途
まず空の変換を作ってから、あとで translate や rotate などを積み上げる基本形です。

-- アフィン変換を生成.
local t = playdate.geometry.affineTransform.new()
 

new(m11, m12, m21, m22, tx, ty)
6 要素を明示して新しいアフィン変換を作ります。
引数
  • m11: number
  • m12: number
  • m21: number
  • m22: number
  • tx: number
  • ty: number
戻り値
  • _AffineTransform
意味
行列成分を直接指定して変換を構築します。
注意
identity が欲しいだけなら引数なし版を使う前提です。
用途
普通は translate/rotate/scale を使うほうが安全です。
この 6 要素版は、
  • 既知の変換行列をそのまま作りたい
  • 自前計算した行列を流し込みたい
とき向けです。

演算子 / メタメソッド

__mul が 3 つ定義されています。Lua 的には *演算子に対応します。
affineTransform:__mul(p)
変換を point に適用し、新しい point を返します。
引数
  • p: _Point
戻り値
  • _Point
意味
transform * point という形で使えるものです。
役割
transformPoint() の「新しい値を返す版」に近い使い勝手です。
元の point を直接書き換えるのではなく、結果の point を得る用途だと考えるのが自然です。

local t = playdate.geometry.affineTransform.new()
t:translate(100, 20)
local p = playdate.geometry.point.new(10, 5)
-- 位置行列を p=(10, 5) で変換.
local p2 = t * p
 

affineTransform:__mul(t)
変換同士を掛け合わせた、新しい変換を返します。
引数
  • t: _AffineTransform
戻り値
  • _AffineTransform
意味
transform1 * transform2 により、複数変換を合成します。
重要
行列演算は可換ではありません。
つまり、
  • t1 * t2
  • t2 * t1
は一般に別結果です。
実務上の意味
たとえば
  • 先に回転してから移動
  • 先に移動してから回転
は結果が変わります。

affineTransform:__mul(v)
変換を vector2D に適用し、新しい vector2D を返します。
引数
  • v: _Vector2D
戻り値
  • _Vector2D
意味
transform * vector に相当します。
point との違い
point は位置なので通常 tx, ty の影響を受けますが、vector は「方向・差分」として扱われることが多く、平行移動成分の扱いは点と意味合いが異なります。

変換の合成・複製・初期化

affineTransform:concat(af)
呼び出し元を破壊的に変更し、別の変換 af を連結します。
引数
  • af: _AffineTransform
戻り値
  • nil
意味
現在の変換に追加で別の変換を合成します。
説明の要点
  • 呼び出し元を mutate する
  • 複数の変換を 1 つにまとめるためのもの
  • 順序は重要
  • 行列演算は非可換
*演算子との違い
  • t1 * t2 は新しい transform を返す
  • t1:concat(t2) は t1 自体を書き換える

local t = playdate.geometry.affineTransform.new()
t:translate(50, 0)
t:concat(otherTransform)
 

affineTransform:copy()
変換のコピーを返します。
戻り値
  • _AffineTransform
意味
元を壊さずに分岐したいときに使います。

local base = playdate.geometry.affineTransform.new()
base:translate(20, 30)
local rotated = base:copy()
rotated:rotate(45)
 

affineTransform:invert()
呼び出し元を逆変換行列に書き換えます。
戻り値
  • nil
意味
ある変換の「逆操作」を行うための変換にします。
説明の要点
  • (x, y) を変換して (x', y') になったなら
  • その逆行列を (x', y') にかけると (x, y) に戻せる
用途
  • 変換後座標から元座標に戻す
  • ローカル座標系とワールド座標系を往復する
  • ヒット判定時に逆変換で元形状に戻して考える
注意
数学的には逆行列を持たないケースがあります。
たとえば scale で 0 倍したような行列は逆にできません。stub はその失敗時挙動までは書いていません。

affineTransform:reset()
呼び出し元を単位変換に戻します。
戻り値
  • nil
意味
今まで積んだ
  • translate
  • rotate
  • scale
  • skew
を全部リセットして、「何もしない変換」に戻します。

回転系

回転は rotate と rotatedBy があり、それぞれ point 指定版と x,y 指定版があります。
affineTransform:rotate(angle, point)
呼び出し元に回転を追加します。破壊的変更です。
引数
  • angle: number
  • point?: _Point
戻り値
  • nil
意味
角度 angle 度だけ回転を適用します。
重要
  • 正の値: clockwise
  • 負の値: counterclockwise
となっています。
これは一般的な数学座標系の「正で反時計回り」と逆なので、Playdate の座標系前提の仕様として意識したほうがよいです。
pivot
point を指定すると、その点を中心に回転します。
未指定なら (0, 0) 周りです。

affineTransform:rotate(angle, x, y)
中心を point ではなく数値座標で指定して回転します。
引数
  • angle: number
  • x?: integer
  • y?: integer
戻り値
  • nil
意味
(x, y) を中心に回転します。
未指定なら (0, 0) です。

affineTransform:rotatedBy(angle, point)
元の transform を壊さず、回転を追加した新しい transform を返します。
引数
  • angle: number
  • point?: _Point
戻り値
  • _AffineTransform
意味
rotate() の非破壊版です。

local t2 = t1:rotatedBy(90)
 

affineTransform:rotatedBy(angle, x, y)
x,y 指定して回転を行った新しい transform を返します。
引数
  • angle: number
  • x?: integer
  • y?: integer
戻り値
  • _AffineTransform

拡大縮小系

affineTransform:scale(sx, sy)
呼び出し元に拡大縮小を追加します。破壊的変更です。
引数
  • sx: number
  • sy?: number
戻り値
  • nil
意味
  • sx で x 軸方向の倍率
  • sy で y 軸方向の倍率
省略時
sy を省略すると、sx を両軸に使います。
つまり一様スケールです。

t:scale(2)      -- x,y ともに 2 倍
t:scale(2, 0.5) -- x は 2 倍、y は 0.5 倍
 

affineTransform:scaledBy(sx, sy)
元を壊さず、スケール追加済みの新しい transform を返します。
引数
  • sx: number
  • sy?: number
戻り値
  • _AffineTransform
意味
scale() の非破壊版です。

skew(せん断)系

affineTransform:skew(sx, sy)
呼び出し元に skew 変換を追加します。破壊的変更です。
引数
  • sx: number
  • sy: number
戻り値
  • nil
意味
  • sx: x 軸方向の skew 量
  • sy: y 軸方向の skew 量
単位
degrees です。
補足
skew は、長方形を平行四辺形のように傾ける変換です。
回転と違い、形の角度関係がそのまま保たれないことがあります。

affineTransform:skewedBy(sx, sy)
元を壊さず、skew を追加した新しい transform を返します。
引数
  • sx: number
  • sy: number
戻り値
  • _AffineTransform
意味
skew() の非破壊版です。

平行移動系

affineTransform:translate(dx, dy)
呼び出し元に平行移動を追加します。破壊的変更です。
引数
  • dx: integer
  • dy: integer
戻り値
  • nil
意味
  • x を dx だけ移動
  • y を dy だけ移動

t:translate(32, 16)
 
affineTransform:translatedBy(dx, dy)
元を壊さず、平行移動追加済みの新しい transform を返します。
引数
  • dx: integer
  • dy: integer
戻り値
  • _AffineTransform

ジオメトリへの適用(破壊的変更版)

これらは対象オブジェクト自体を書き換えます。
affineTransform:transformAABB(r)
axis aligned bounding box である rect r に変換を適用し、その rect を変更します。
引数
  • r: _Rect
戻り値
  • nil
意味
AABB は「軸に平行な境界ボックス」です。
回転後の図形そのものではなく、回転後図形を包む軸平行矩形 を扱う文脈で使われる名前です。
注意
回転をかけると、もとの rect と全く同じ意味の矩形にはなりません。
「回転した四角形」そのものではなく、「それを囲う軸平行矩形」として結果を見る必要があります。

affineTransform:transformLineSegment(ls)
line segment に変換を適用し、その line segment を変更します。
引数
  • ls: _LineSegment
戻り値
  • nil

affineTransform:transformPoint(p)
point に変換を適用し、その point を変更します。
引数
  • p: _Point
戻り値
  • nil
用途
point をその場で更新したいときに使います。

affineTransform:transformPolygon(p)
  • polygon に変換を適用し、その polygon を変更します。
引数
  • p: _Polygon
戻り値
  • nil

affineTransform:transformXY(x, y)
座標 (x, y) に変換を適用し、変換後の x, y を数値 2 つで返します。
引数
  • x: integer
  • y: integer
戻り値
  • number x
  • number y
意味
point オブジェクトを作らずに、その場で数値だけ変換したいときに便利です。
利点
  • point 生成が不要
  • 軽く使いやすい
  • 一時座標の計算向き

local x2, y2 = t:transformXY(10, 20)
 

ジオメトリへの適用(非破壊版)

これらは元を変更せず、新しいオブジェクトを返します。
affineTransform:transformedAABB(r)
rect r を変換した結果を、新しい rect として返します。
引数
  • r: _Rect
戻り値
  • _Rect
意味
transformAABB() の非破壊版です。

affineTransform:transformedLineSegment(ls)
line segment を変換した新しい line segment を返します。
引数
  • ls: _LineSegment
戻り値
  • _LineSegment

affineTransform:transformedPoint(p)
point を変換した新しい point を返します。
引数
  • p: _Point
戻り値
  • _Point

affineTransform:transformedPolygon(p)
polygon を変換した新しい polygon を返します。
引数
  • p: _Polygon
戻り値
  • _Polygon

資料

破壊的版と非破壊版の整理
affineTransform ではかなり一貫しています。
transform を変更する系
  • concat
  • invert
  • reset
  • rotate
  • scale
  • skew
  • translate
変換対象を変更する系
  • transformAABB
  • transformLineSegment
  • transformPoint
  • transformPolygon
新しい transform を返す系
  • copy
  • rotatedBy
  • scaledBy
  • skewedBy
  • translatedBy
  • __mul(t) の変換同士合成
新しい図形を返す系
  • transformedAABB
  • transformedLineSegment
  • transformedPoint
  • transformedPolygon
  • __mul(p)
  • __mul(v)

API 設計上の読みどころ
affineTransform の設計はかなり明快で、次の思想があります。
1. 破壊的と非破壊的が分かれている
たとえば回転なら
  • rotate(...) → 呼び出し元を書き換える
  • rotatedBy(...) → 新しい transform を返す
図形への適用も
  • transformPoint(p) → p を書き換える
  • transformedPoint(p) → 新しい point を返す
で対になっています。
これはかなり使いやすいです。
2. 演算子 * でも扱える
__mul (operator*) が実装されているので、
  • transform * point
  • transform * vector
  • transform1 * transform2
ができるので、数式的に書きやすいです。
3. pivot 回転に対応している
rotate(angle, point) / rotate(angle, x, y) があるため、
  • 原点中心回転だけでなく
  • 任意点中心回転
がやれます。
これはスプライト中心回転や UI パーツ回転で便利です。
4. AABB を明示的に区別している
transformAABB / transformedAABB という名前になっていて、
単に rect を transform するというより、軸平行 bounding box として扱う API であることが明確です。

典型的な使い方

-- 1. 基本変換を積む
local geom = playdate.geometry
local t = geom.affineTransform.new()
t:translate(100, 50)
t:rotate(30)
t:scale(2)
 
これは 1 つの transform に複数操作を蓄積している形です。

-- 2. point に適用
local p = geom.point.new(10, 20)
local p2 = t:transformedPoint(p)
 
元の p を残したいならこれです。
t:transformPoint(p)
 
なら p 自体が更新されます。

-- 3. 数値だけ変換
local x2, y2 = t:transformXY(10, 20)
 
point を作らなくてよいので軽量です。

-- 4. 元を残しつつ変換を分岐
local base = geom.affineTransform.new()
base:translate(100, 100)
local a = base:rotatedBy(15)
local b = base:rotatedBy(-15)
 

-- 5. 逆変換
local inv = t:copy()
inv:invert()
local original = inv:transformedPoint(p2)
 
変換後座標から元座標へ戻す用途です。

注意点

1. 回転の正方向
affineTransformでは
  • 正: clockwise
  • 負: counterclockwise
です。
数学や他ライブラリと感覚が逆なことがあるので注意です。
2. 変換順序が重要
行列計算の特性上、translate→rotate と rotate→translate は別物です。
3. transformAABB は「回転した四角形そのもの」ではない
名前の通り AABB です。
回転した結果の外接軸平行矩形を扱う理解が必要です。
4. プロパティを直接読む前提ではない
affineTransformは内部成分を直接使うより、メソッドと *演算子で扱う前提の型です。


関連ページ

最終更新:2026年04月22日 08:20