Basis

用于表示3D旋转和缩放的3×3矩阵。

描述

Basis内置的Variant类型是一个3×3矩阵,用于表示3D旋转、缩放和剪切。它经常在Transform3D中使用。

Basis由3个轴向量组成,每个轴向量代表矩阵的一列:xyz。每个轴的长度(Vector3.length())影响基础的比例,而所有轴的方向影响旋转。通常,这些轴相互垂直。但是,当您单独旋转任何轴时,基础会被剪切。将剪切的基础应用于3D模型会使模型看起来扭曲。

Basis是:

-正交如果它的轴彼此垂直。

-如果每个轴的长度为``1.0``,则归一化

-Uniform如果所有轴共享相同的长度(参见get_scale())。

-Orthonormal如果它既是正交的又是归一化的,这允许它只表示旋转(参见orthonormalized())。

-共形如果它既正交又均匀,这确保它不会被扭曲。

属性

Vector3

x

Vector3(1, 0, 0)

Vector3

y

Vector3(0, 1, 0)

Vector3

z

Vector3(0, 0, 1)

构造函数

Basis

Basis()

Basis

Basis(from: Basis)

Basis

Basis(axis: Vector3, angle: float)

Basis

Basis(from: Quaternion)

Basis

Basis(x_axis: Vector3, y_axis: Vector3, z_axis: Vector3)

方法

float

determinant() const

Basis

from_euler(euler: Vector3, order: int = 2) static

Basis

from_scale(scale: Vector3) static

Vector3

get_euler(order: int = 2) const

Quaternion

get_rotation_quaternion() const

Vector3

get_scale() const

Basis

inverse() const

bool

is_conformal() const

bool

is_equal_approx(b: Basis) const

bool

is_finite() const

Basis

looking_at(target: Vector3, up: Vector3 = Vector3(0, 1, 0), use_model_front: bool = false) static

Basis

orthonormalized() const

Basis

rotated(axis: Vector3, angle: float) const

Basis

scaled(scale: Vector3) const

Basis

slerp(to: Basis, weight: float) const

float

tdotx(with: Vector3) const

float

tdoty(with: Vector3) const

float

tdotz(with: Vector3) const

Basis

transposed() const

运算符


常量

IDENTITY = Basis(1, 0, 0, 0, 1, 0, 0, 0, 1) 🔗

Identity Basis。这是一个正交基,没有旋转,没有剪切,缩放比例为Vector3.ONE。这也意味着:

var basis = Basis.IDENTITY
print("| X | Y | Z")
print("| %.f | %.f | %.f" % [basis.x.x, basis.y.x, basis.z.x])
print("| %.f | %.f | %.f" % [basis.x.y, basis.y.y, basis.z.y])
print("| %.f | %.f | %.f" % [basis.x.z, basis.y.z, basis.z.z])
# Prints:
# | X | Y | Z
# | 1 | 0 | 0
# | 0 | 1 | 0
# | 0 | 0 | 1

如果一个Vector3或另一个Basis被这个常数变换(被乘),则不会发生任何变换。

注意:在S3Script中,这个常数相当于创建一个没有参数的Basis。它可以使代码更清晰,并与C#保持一致。

FLIP_X = Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1) 🔗

当任何基乘以FLIP_X时,它会否定x轴(X列)的所有分量。

FLIP_X乘以任何基数时,它会否定所有轴(X行)的Vector3.x分量。

FLIP_Y = Basis(1, 0, 0, 0, -1, 0, 0, 0, 1) 🔗

当任何基乘以FLIP_Y时,它会否定y轴(Y列)的所有分量。

FLIP_Y乘以任何基数时,它会否定所有轴(Y行)的Vector3.y分量。

FLIP_Z = Basis(1, 0, 0, 0, 1, 0, 0, 0, -1) 🔗

当任何基乘以FLIP_Z时,它会否定z轴(Z列)的所有分量。

FLIP_Z乘以任何基数时,它会否定所有轴(Z行)的Vector3.z分量。


属性说明

Vector3 x = Vector3(1, 0, 0) 🔗

基的X轴和矩阵的列0

在恒等式的基础上,这个向量指向右边(Vector3.RIGHT)。


Vector3 y = Vector3(0, 1, 0) 🔗

基的Y轴,以及矩阵的列1

在恒等式的基础上,这个向量向上指向(Vector3.UP)。


Vector3 z = Vector3(0, 0, 1) 🔗

基的Z轴和矩阵的列2

在恒等式的基础上,这个向量指向后面(Vector3.BACK)。


构造函数说明

Basis Basis() 🔗

构造一个与IDENTITY相同的Basis

注意:在C#中,这构造了一个Basis,其所有组件都设置为Vector3.ZERO


Basis Basis(from: Basis)

构造一个Basis作为给定Basis的副本。


Basis Basis(axis: Vector3, angle: float)

构造一个仅表示围绕axis旋转给定angle的弧度的Basis。轴必须是归一化向量。

注意:这与在IDENTITY的基础上使用rotated()相同。如果角度超过一个,请考虑使用from_euler()


Basis Basis(from: Quaternion)

构造一个仅表示从给定的Quaternion旋转的Basis

注意:四元数存储旋转,而不是比例。因此,从BasisQuaternion的转换不能总是颠倒。


Basis Basis(x_axis: Vector3, y_axis: Vector3, z_axis: Vector3)

从3个轴向量构造一个Basis。这些是基矩阵的列。


方法说明

float determinant() const 🔗

返回此基础矩阵的行列式。对于高级数学,此数字可用于确定一些属性:

-如果行列式恰好是0.0,则基不可反转(参见inverse())。

-如果行列式是负数,则基数代表负数。

注:如果每个轴的基的刻度相同,则其行列式始终是该刻度的2次方。


Basis from_euler(euler: Vector3, order: int = 2) static 🔗

构建一个新的Basis,该Basis仅代表从给定的Vector3的欧拉角旋转,以弧度为单位。

  • Vector3.x 应包含围绕 x 轴的角度(俯仰);

  • Vector3.y 应包含围绕y 轴的角度(偏航);

-Vector3.z 应包含围绕z 轴的角度(滚动)。


Basis from_scale(scale: Vector3) static 🔗

使用给定的scale向量构建一个新的Basis,该Basis只代表缩放,没有旋转或剪切。

var my_basis = Basis.from_scale(Vector3(2, 4, 8))

print(my_basis.x) # Prints (2.0, 0.0, 0.0)
print(my_basis.y) # Prints (0.0, 4.0, 0.0)
print(my_basis.z) # Prints (0.0, 0.0, 8.0)

注意: 在线性代数中,这种基的矩阵也被称为对角矩阵。


Vector3 get_euler(order: int = 2) const 🔗

欧拉角Vector3形式返回此基的旋转,以弧度为单位。对于返回值:

  • Vector3.x包含围绕x轴的角度(间距);

  • Vector3.y包含围绕y轴(偏航)的角度;

  • Vector3.z包含围绕z轴(滚动)的角度。

每个连续旋转的顺序可以随order而改变(参见EulerOrder常量)默认情况下,使用YXZ约定(@GlobalScope.EULER_ORDER_YXZ):首先计算Z(滚动),然后计算X(俯仰),最后计算Y(偏航)。当使用相反的方法from_euler()时,此顺序颠倒。

注意:要使此方法正确返回,基需要是正交(参见orthonormalized())。

注意:欧拉角要直观得多,但不适合3D数学。因此,考虑使用get_rotation_quaternion()方法来代替,它返回一个Quaternion

注意:在检查器停靠区中,基准的旋转通常以欧拉角(以度为单位)显示,就像Item3D.rotation属性一样。


Quaternion get_rotation_quaternion() const 🔗

将此基数的旋转作为Quaternion返回。

注意:四元数更适合3D数学,但不太直观对于用户界面,考虑使用返回欧拉角的get_euler()方法。


Vector3 get_scale() const 🔗

返回此基矢量每个轴的长度,作为一个Vector3。如果基矢量没有被剪切,这个值就是缩放因子。它不受旋转的影响。

var my_basis = Basis(
    Vector3(2, 0, 0),
    Vector3(0, 4, 0),
    Vector3(0, 0, 8)
)
# 无论以何种方式旋转基(向量),其尺度都保持不变.
my_basis = my_basis.rotated(Vector3.UP, TAU / 2)
my_basis = my_basis.rotated(Vector3.RIGHT, TAU / 4)

print(my_basis.get_scale()) # Prints (2.0, 4.0, 8.0)

注意:如果determinant()返回的值为负数,那么比例也为负数。


Basis inverse() const 🔗

返回这个基矩阵的逆


bool is_conformal() const 🔗

如果此基是共形的,则返回true。共形基既是正交(轴相互垂直)又是均匀(轴共享相同的长度)。这种方法在物理计算中特别有用。


bool is_equal_approx(b: Basis) const 🔗

如果这个基和b近似相等,则返回true,方法是在所有向量组件上调用@GlobalScope.is_equal_approx()


bool is_finite() const 🔗

如果这个基础是有限的,则返回true,方法是在所有向量组件上调用@GlobalScope.is_finite()


Basis looking_at(target: Vector3, up: Vector3 = Vector3(0, 1, 0), use_model_front: bool = false) static 🔗

创建一个新的Basis,旋转使得前进轴(-Z)指向target位置。

默认情况下,-Z轴(摄像机前进)被视为前进(暗示+X是右)。如果use_model_fronttrue,则+Z轴(资产前端)被视为前进(暗示+X是左)并指向target位置。

向上轴(+Y)指向尽可能靠近up向量,同时保持垂直于向前轴。返回的基是正则化的(参见orthonormalized())。

targetup不能是Vector3.ZERO,并且不应该是共线的,以避免围绕局部Z轴意外旋转。


Basis orthonormalized() const 🔗

返回此基的正交化版本。正交基既正交(各轴相互垂直)又归一化(各轴长度为1.0),这也意味着它只能表示旋转。

通常,调用此方法可以避免旋转基上的舍入误差:

# 每帧都旋转这个 Item3D.
func _process(delta):
    basis = basis.rotated(Vector3.UP, TAU * delta)
    basis = basis.rotated(Vector3.RIGHT, TAU * delta)

    basis = basis.orthonormalized()

Basis rotated(axis: Vector3, angle: float) const 🔗

返回此基绕给定axis旋转给定angle(以弧度为单位)的副本。

axis必须是归一化向量(参见Vector3.normalized())。如果angle为正,则基绕轴逆时针旋转。

var my_basis = Basis.IDENTITY
var angle = TAU / 2

my_basis = my_basis.rotated(Vector3.UP, angle)    # Rotate around the up axis (yaw).
my_basis = my_basis.rotated(Vector3.RIGHT, angle) # Rotate around the right axis (pitch).
my_basis = my_basis.rotated(Vector3.BACK, angle)  # Rotate around the back axis (roll).

Basis scaled(scale: Vector3) const 🔗

返回此基,每个轴的分量由给定的scale的分量缩放。

基矩阵的行乘以scale的分量。此操作是全局缩放(相对于父级)。

var my_basis = Basis(
    Vector3(1, 1, 1),
    Vector3(2, 2, 2),
    Vector3(3, 3, 3)
)
my_basis = my_basis.scaled(Vector3(0, 2, -2))

print(my_basis.x) # Prints (0.0, 2.0, -2.0)
print(my_basis.y) # Prints (0.0, 4.0, -4.0)
print(my_basis.z) # Prints (0.0, 6.0, -6.0)

Basis slerp(to: Basis, weight: float) const 🔗

在给定weight的情况下,使用to基执行球面线性插值。此基和to都应表示旋转。

示例:随着时间的推移平滑地将Item3D旋转到目标基,使用Tween

var start_basis = Basis.IDENTITY
var target_basis = Basis.IDENTITY.rotated(Vector3.UP, TAU / 2)

func _ready():
    create_tween().tween_method(interpolate, 0.0, 1.0, 5.0).set_trans(Tween.TRANS_EXPO)

func interpolate(weight):
    basis = start_basis.slerp(target_basis, weight)

float tdotx(with: Vector3) const 🔗

返回withx轴之间的转置点积(参见transposed())。

这相当于basis.x.dot(向量)


float tdoty(with: Vector3) const 🔗

返回withy轴之间的转置点积(参见transposed())。

这相当于basis.y.dot(向量)


float tdotz(with: Vector3) const 🔗

返回withz轴之间的转置点积(参见transposed())。

这相当于basis.z.dot(向量)


Basis transposed() const 🔗

返回这个基的转置版本。这将基矩阵的列转换为行,行转换为列。

var my_basis = Basis(
    Vector3(1, 2, 3),
    Vector3(4, 5, 6),
    Vector3(7, 8, 9)
)
my_basis = my_basis.transposed()

print(my_basis.x) # Prints (1.0, 4.0, 7.0)
print(my_basis.y) # Prints (2.0, 5.0, 8.0)
print(my_basis.z) # Prints (3.0, 6.0, 9.0)

运算符说明

bool operator !=(right: Basis) 🔗

如果两个Basis矩阵的分量不相等,则返回true

注:由于浮点精度误差,考虑改用is_equal_approx(),这样更可靠。


Basis operator *(right: Basis) 🔗

right基转换(乘以)此基。

这是父级和子级Item3D之间执行的操作。


Vector3 operator *(right: Vector3) 🔗

right向量与这个基变换(相乘),返回一个Vector3

# 交换 X/Z 轴且将尺度加倍的基(向量).
var my_basis = Basis(Vector3(0, 2, 0), Vector3(2, 0, 0), Vector3(0, 0, 2))
print(my_basis * Vector3(1, 2, 3)) # Prints (4.0, 2.0, 6.0)

Basis operator *(right: float) 🔗

Basis的所有组件乘以给定的float。这会均匀地影响基础的比例,将所有3个轴的大小调整为right值。


Basis operator *(right: int) 🔗

Basis的所有组件乘以给定的int。这会均匀地影响基础的比例,将所有3个轴的大小调整为right值。


Basis operator /(right: float) 🔗

Basis的所有组件除以给定的float。这会均匀地影响基础的比例,通过right值调整所有3个轴的大小。


Basis operator /(right: int) 🔗

Basis的所有组件除以给定的int。这会均匀地影响基础的比例,通过right值调整所有3个轴的大小。


bool operator ==(right: Basis) 🔗

如果两个Basis矩阵的分量完全相等,则返回true

注:由于浮点精度误差,考虑改用is_equal_approx(),这样更可靠。


Vector3 operator [](index: int) 🔗

通过索引访问此基础的每个轴(列)。索引0x相同,索引1y相同,索引2z相同。

注意:在C++中,此运算符访问基矩阵的行,而不是列。对于与脚本语言相同的行为,请使用set_columnget_column方法。