回転


title: "回転" description: "mat2回転行列を使った座標の回転を学びます。任意の点を中心に図形を回転させる方法を理解しましょう。" chapter: "05-transforms" order: 1 challenge: description: "回転する十字型を描いてください。2つの矩形(縦長と横長)のunionで十字を作り、u_timeで回転させましょう。" hints:

  • "十字型は2つの矩形のmin(union)で作れます。例:min(sdBox(p, vec2(0.05, 0.2)), sdBox(p, vec2(0.2, 0.05)))"
  • "回転はSDFに渡す座標 p に回転行列を掛けます。rot2(u_time) * p のように。"
  • "回転行列を適用してから十字のSDFを計算しましょう:vec2 rp = rot2(u_time) * p; float d = min(sdBox(rp, ...), sdBox(rp, ...));"

回転

2D回転行列

2Dの回転は回転行列を使います。角度 a(ラジアン)で座標を回転させる行列は:

mat2 rot2(float a) {
    float c = cos(a);
    float s = sin(a);
    return mat2(c, -s, s, c);
}

GLSLの mat2 は2x2の行列です。座標に掛けることで回転が適用されます:

vec2 rotated = rot2(angle) * p;

SDFに回転を適用する

SDFで図形を回転させるには、座標を逆方向に回転させてからSDF関数に渡します。

これは直感的でないかもしれませんが、考え方はシンプルです:図形を時計回りに30度回転させたいなら、空間を反時計回りに30度回転させれば同じ結果になります。

vec2 p = uv - vec2(0.5);
p = rot2(0.5) * p;  // 空間を回転
float d = sdBox(p, vec2(0.2, 0.1)); // 回転した矩形が描かれる

任意の点を中心に回転

デフォルトでは原点を中心に回転します。任意の点を中心にしたい場合は:

  1. 中心点を引いて原点に移動
  2. 回転を適用
  3. 中心点を足して戻す
vec2 center = vec2(0.3, 0.2);
vec2 p = uv - center;
p = rot2(angle) * p;
float d = sdBox(p, vec2(0.1, 0.05));

u_timeでアニメーション

u_time を回転角度に使うと、図形が連続的に回転します:

p = rot2(u_time) * p;

u_time は秒単位で増加するので、約6.28秒(2π)で一回転します。速度を変えるには u_time に係数を掛けます:

p = rot2(u_time * 2.0) * p; // 2倍速

まとめ

  • 2D回転は mat2(cos, -sin, sin, cos) で表現
  • 図形を回転させるには座標を逆回転させてSDFに渡す
  • 中心をずらして回転するには、座標を中心基準に変換する
  • u_time を使って連続回転アニメーションが可能