# 矩阵与变换¶

## 前言¶

### 缩放变换矩阵¶

```var t = Transform2D()
# Scale
t.x *= 2
t.y *= 2
transform = t # Change the node's transform to what we just calculated.
```

### 旋转变换矩阵¶

Godot 用弧度表示所有的旋转，不用角度。完整转一圈是 TAUPI*2 弧度，90 度的四分之一圈是 TAU/4PI/2 弧度。使用 TAU 通常会让代码更易读。

```var rot = 0.5 # The rotation to apply.
var t = Transform2D()
t.x.x = cos(rot)
t.y.y = cos(rot)
t.x.y = sin(rot)
t.y.x = -sin(rot)
transform = t # Change the node's transform to what we just calculated.
```

### 变换矩阵的平移¶

origin 向量的修改称为对变换矩阵的平移。平移其实上是“移动”对象的一个技术术语，但它不会包含任何旋转。

Godot 的 2D 使用基于像素的坐标，所以在实际项目中，你会想要转换成数百个单位。

### 融会贯通¶

```var t = Transform2D()
# Translation
t.origin = Vector2(350, 150)
# Rotation
var rot = -0.5 # The rotation to apply.
t.x.x = cos(rot)
t.y.y = cos(rot)
t.x.y = sin(rot)
t.y.x = -sin(rot)
# Scale
t.x *= 3
t.y *= 3
transform = t # Change the node's transform to what we just calculated.
```

### 剪切变换矩阵（高级）¶

```var t = Transform2D()
# Shear by setting Y to (1, 1)
t.y = Vector2.ONE
transform = t # Change the node's transform to what we just calculated.
```

## 变换的实际应用¶

### 在变换之间转换位置¶

```# World space vector 100 units below the player.
print(transform.xform(Vector2(0, 100)))
```

```# Where is (0, 100) relative to the player?
print(transform.xform_inv(Vector2(0, 100)))
```

### 相对于对象本身移动对象¶

```transform.origin += transform.x * 100
```

### 将变换应用于变换¶

```# Set up transforms just like in the image, except make positions be 100 times bigger.
var parent = Transform2D(Vector2(2, 0), Vector2(0, 1), Vector2(100, 200))
var child = Transform2D(Vector2(0.5, 0), Vector2(0, 0.5), Vector2(100, 100))

# Calculate the child's world space transform
# origin = (2, 0) * 100 + (0, 1) * 100 + (100, 200)
var origin = parent.x * child.origin.x + parent.y * child.origin.y + parent.origin
# basis_x = (2, 0) * 0.5 + (0, 1) * 0
var basis_x = parent.x * child.x.x + parent.y * child.x.y
# basis_y = (2, 0) * 0 + (0, 1) * 0.5
var basis_y = parent.x * child.y.x + parent.y * child.y.y

# Change the node's transform to what we just calculated.
transform = Transform2D(basis_x, basis_y, origin)
```

```# Set up transforms just like in the image, except make positions be 100 times bigger.
var parent = Transform2D(Vector2(2, 0), Vector2(0, 1), Vector2(100, 200))
var child = Transform2D(Vector2(0.5, 0), Vector2(0, 0.5), Vector2(100, 100))

# Change the node's transform to what would be the child's world transform.
transform = parent * child
```

### 求逆变换矩阵¶

"affine_inverse" 函数返回一个 "撤销" 前一个转换的转换. 这在某些情况下可能很有用, 但只提供几个示例会更容易.

```var ti = transform.affine_inverse()
var t = ti * transform
# The transform is the identity transform.
```

```var ti = transform.affine_inverse()
position = transform.xform(position)
position = ti.xform(position)
# The position is the same as before.
```

## 这一切是如何在 3D 模式下工作的？¶

### 表示 3D 中的旋转（高级）¶

2D 和 3D 变换矩阵之间最大的区别在于您如何在没有基向量的情况下自行表示旋转。

http://www.bilibili.com/video/BV1fx41187tZ

http://www.bilibili.com/video/BV1SW411y7W1

https://eater.net/quaternions