Up to date

This page is up to date for Godot `4.2`. If you still find outdated information, please open an issue.

# 矩阵与变换¶

## 前言¶

### 缩放变换矩阵¶

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

### 旋转变换矩阵¶

Godot 用弧度（radians）表示所有的旋转，不用角度。完整转一圈是 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 calculated.
```

To calculate the object's rotation from an existing transformation matrix, you can use `atan2(t.x.y, t.x.x)`, where t is the Transform2D.

In actual projects, you can use the `rotated()` method to perform rotations.

### 变换矩阵的基¶

So far we have only been working with the `x` and `y`, vectors, which are in charge of representing rotation, scale, and/or shearing (advanced, covered at the end). The X and Y vectors are together called the basis of the transformation matrix. The terms "basis" and "basis vectors" are important to know.

You might have noticed that Transform2D actually has three Vector2 values: `x`, `y`, and `origin`. The `origin` value is not part of the basis, but it is part of the transform, and we need it to represent position. From now on we'll keep track of the origin vector in all examples. You can think of origin as another column, but it's often better to think of it as completely separate.

Note that in 3D, Godot has a separate Basis structure for holding the three Vector3 values of the basis, since the code can get complex and it makes sense to separate it from Transform3D (which is composed of one Basis and one extra Vector3 for the origin).

### 变换矩阵的平移¶

Changing the `origin` vector is called translating the transformation matrix. Translating is basically a technical term for "moving" the object, but it explicitly does not involve any rotation.

If we want to move the object to a position of (1, 2), we need to set its `origin` vector to (1, 2):

There is also a `translated()` method, which performs a different operation to adding or changing `origin` directly. The `translated()` method will translate the object relative to its own rotation. For example, an object rotated 90 degrees clockwise will move to the right when `translated()` with `Vector2.UP`.

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

### 融会贯通¶

We're going to apply everything we mentioned so far onto one transform. To follow along, create a project with a Sprite2D node and use the Godot logo for the texture resource.

```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 calculated.
```

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

Node2D provides a shearing property out of the box.

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

## 变换的实际应用¶

In actual projects, you will usually be working with transforms inside transforms by having multiple Node2D or Node3D nodes parented to each other.

However, it's useful to understand how to manually calculate the values we need. We will go over how you could use Transform2D or Transform3D to manually calculate transforms of nodes.

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

We can find what a vector relative to the player would be defined in world space as using the `*` operator:

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

And we can use the `*` operator in the opposite order to find a what world space position would be if it was defined relative to the player:

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

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

Since the basis vectors are the orientation relative to the parent, and the origin vector is the position relative to the parent, we can add multiples of the basis vectors to move an object relative to itself.

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

In actual projects, you can use `translate_object_local` in 3D or `move_local_x` and `move_local_y` in 2D to do this.

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

All child transformations are affected by the parent transformations. The child has a scale of (0.5, 0.5), so you would expect it to be a 1:1 ratio square, and it is, but only relative to the parent. The child's X vector ends up being (1, 0) in world space, because it is scaled by the parent's basis vectors. Similarly, the child node's `origin` vector is set to (1, 1), but this actually moves it (2, 1) in world space, due to the parent node's basis vectors.