Basis

Матриця 3×3 для представлення тривимірного обертання та масштабу.

Опис

Вбудований тип Basis Variant — це матриця 3×3, яка використовується для представлення тривимірного обертання, масштабу та зсуву. Він часто використовується в Transform3D.

Basis складається з 3 осьових векторів, кожен з яких представляє стовпець матриці: x, y і z. Довжина кожної осі (Vector3.length()) впливає на масштаб основи, тоді як напрямок усіх осей впливає на поворот. Зазвичай ці осі перпендикулярні одна одній. Однак, коли ви обертаєте будь-яку вісь окремо, основа стає зрізаною. Застосування зрізаної основи до 3D-моделі змусить модель виглядати спотвореною.

Основа це:

  • Ортогональний, якщо його осі перпендикулярні одна одній.

  • Нормалізовано, якщо довжина кожної осі дорівнює 1,0.

  • **Однакова **, якщо всі осі мають однакову довжину (див. get_scale()).

  • Ортонормальний, якщо він одночасно ортогональний і нормалізований, що дозволяє йому представляти лише обертання (див. orthonormalized()).

  • Конформний, якщо він одночасно ортогональний і рівномірний, що гарантує його відсутність спотворень.

Щоб отримати загальні відомості, перегляньте посібник Матриці та перетворення.

**Примітка: ** Godot використовує правосторонню систему координат, яка є загальним стандартом. Для напрямків угода для вбудованих типів, як-от Camera3D, полягає в тому, що -Z вказує вперед (+X — праворуч, +Y — вгору, а +Z — назад). Інші об’єкти можуть використовувати інші умовні позначення напрямку. Щоб отримати додаткові відомості, перегляньте навчальний посібник Умови щодо напрямків 3D-активів.

Примітка. Основні матриці представлені як головний-стовпець порядок, який є таким самим, як і OpenGL. Однак вони зберігаються всередині в порядку старших рядків, що є таким же, як і DirectX.

Примітка

Існують значні відмінності при використанні цього API із С#. Більше інформації: ref:doc_c_sharp_differences.

Посібники

Властивості

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

scaled_local(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

Оператори

bool

operator !=(right: Basis)

Basis

operator *(right: Basis)

Vector3

operator *(right: Vector3)

Basis

operator *(right: float)

Basis

operator *(right: int)

Basis

operator /(right: float)

Basis

operator /(right: int)

bool

operator ==(right: Basis)

Vector3

operator [](index: int)


Константи

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

Ідентичність Основа. Це ортонормований базис без обертання, без зсуву та масштабом 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])
# Відбитки:
# | X | Y | Z
# | 1 | 0 | 0
# | 0 | 1 | 0
# | 0 | 0 | 1

Якщо Vector3 або інший Basis трансформується (помножується) на цю константу, перетворення не відбувається.

Примітка: у GDScript ця константа еквівалентна створенню основи конструктора без будь-яких аргументів. Його можна використовувати, щоб зробити ваш код зрозумілішим і узгоджено з C#.

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

Коли будь-який базис множиться на FLIP_X, він заперечує всі компоненти осі x (стовпець X).

Коли FLIP_X помножити на будь-яку основу, вона заперечує компонент Vector3.x усіх осей (рядок X).

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

Коли будь-який базис множиться на FLIP_Y, він заперечує всі компоненти осі y (стовпець Y).

Коли FLIP_Y помножити на будь-яку основу, вона заперечує компонент Vector3.y усіх осей (рядка Y).

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

Коли будь-який базис множиться на FLIP_Z, він заперечує всі компоненти осі z (стовпець Z).

Коли FLIP_Z помножити на будь-яку основу, вона заперечує компонент Vector3.z усіх осей (рядок 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() 🔗

Створює Basis, ідентичний IDENTITY.

Примітка: у C# це створює Basis з усіма його компонентами, встановленими на Vector3.ZERO.


Basis Basis(from: Basis)

Створює Basis як копію даного Basis.


Basis Basis(axis: Vector3, angle: float)

Будує Basis, який представляє лише обертання, обертаючись навколо осі axis на заданий angle, у радіанах. Вісь має бути нормалізованим вектором.

Примітка: це те саме, що використовувати rotated() на основі IDENTITY. З більш ніж одним кутом краще використовувати from_euler().


Basis Basis(from: Quaternion)

Будує Basis, який представляє лише обертання від даного Quaternion.

Примітка: ** Кватерніони *лише* зберігають обертання, а не масштаб. Через це перетворення з **Basis на Quaternion не завжди можна скасувати.


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

Будує Basis із 3-х осьових векторів. Це стовпці базисної матриці.


Описи методів

float determinant() const 🔗

Повертає визначник матриці цієї бази. Для просунутої математики це число може бути використане для визначення декількох атрибутів:

  • Якщо визначник дорівнює точно 0.0, база не є оберненою (див. inverse()).

  • Якщо визначник є від'ємним числом, основа представляє від'ємну шкалу.

Примітка: Якщо шкала основи однакова для кожної осі, її визначник завжди дорівнює цій шкалі, піднесеної до степеня 3.


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

Створює новий Basis, який представляє лише обертання від заданого Vector3 кутів Ейлера у радіанах.

  • Vector3.x має містити кут навколо осі x (крок);

  • Vector3.y має містити кут навколо осі y (yaw);

  • Vector3.z має містити кут навколо осі z (крен).

# Створює основу, вісь z якої спрямована вниз.
var my_basis = Basis.from_euler(Vector3(TAU / 4, 0, 0))

print(my_basis.z) # Друк (0.0, -1.0, 0.0)

Порядок кожного послідовного обертання можна змінити за допомогою order (див. EulerOrder константи). За замовчуванням використовується конвенція YXZ (@GlobalScope.EULER_ORDER_YXZ): основа обертається спочатку навколо осі Y (поворот), потім X (нахил) і, нарешті, Z (крен). При використанні протилежного методу get_euler() цей порядок змінюється на протилежний.


Basis from_scale(scale: Vector3) static 🔗

Створює новий Basis, який представляє лише масштаб, без обертання чи зсуву, із заданого вектора scale.

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

print(my_basis.x) # Виводить (2, 0, 0).
print(my_basis.y) # Виводить (0, 4, 0).
print(my_basis.z) # Виводить (0, 0, 8).

Примітка. У лінійній алгебрі матриця цього базису також відома як діагональна матриця.


Vector3 get_euler(order: int = 2) const 🔗

Повертає обертання бази як Vector3 кутів Ейлера у радіанах. Для поверненого значення:

  • Vector3.x містить кут навколо осі х (крок);

  • Vector3.y містить кут навколо осі y (yaw);

  • Vector3.z містить кут навколо осі z (крен).

Порядок кожного послідовного обертання можна змінити за допомогою order (див. EulerOrder константи). За замовчуванням використовується конвенція YXZ (@GlobalScope.EULER_ORDER_YXZ): спочатку обчислюється Z (крен), потім X (нахил) і нарешті Y (рискання). При використанні протилежного методу from_euler() цей порядок змінюється на зворотний.

Примітка: Щоб цей метод повертав правильно, базис має бути ортонормованим (див. orthonormalized()).

**Примітка: ** Кути Ейлера набагато інтуїтивніші, але не підходять для 3D-математики. Через це краще використовувати метод get_rotation_quaternion(), який повертає Quaternion.

Примітка: у доці Inspector обертання основи часто відображається в кутах Ейлера (у градусах), як у випадку з властивістю Node3D.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()) # Друк (2, 4, 8).

Примітка. Якщо значення, яке повертає determinant(), є негативним, шкала також є негативною.


Basis inverse() const 🔗

Повертає обернену до базисної матриці.


bool is_conformal() const 🔗

Повертає true, якщо цей базис конформний. Конформна основа є як ортогональною (осі перпендикулярні одна до одної), так і однорідною (осі мають однакову довжину). Цей метод може бути особливо корисним під час фізичних розрахунків.


bool is_equal_approx(b: Basis) const 🔗

Повертає true, якщо ця основа та b приблизно рівні, шляхом виклику @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 🔗

Створює нову основу з обертанням таким чином, що передня вісь (-Z) вказує на позицію target.

За замовчуванням вісь -Z (передня камера) розглядається як передня (вказує на те, що +X правильна). Якщо use_model_front має значення true, вісь +Z (фронт активу) розглядається як передня (означає, що +X ліворуч) і вказує на позицію target.

Вісь вгору (+Y) спрямована якомога ближче до вектора up, залишаючись перпендикулярною до передньої осі. Повернений базис є ортонормованим (див. orthonormalized()).

target і up не можуть бути Vector3.ZERO і не повинні бути колінеарними, щоб уникнути ненавмисного обертання навколо локальної осі Z.


Basis orthonormalized() const 🔗

Повертає ортонормовану версію цього базису. Ортонормований базис є як ортогональним (осі перпендикулярні одна до одної), так і нормованим (осі мають довжину 1), що також означає, що він може представляти лише обертання.

Часто корисно викликати цей метод, щоб уникнути помилок округлення на ротаційній основі:

# Обертайте цей Node3D кожен кадр.
func _process(delta):
    base = basis.rotated(Vector3.UP, TAU * delta)
    base = basis.rotated(Vector3.RIGHT, TAU * delta)
    base = basis.orthonormalized()

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

Повертає цей базис, повернутий навколо заданої axis на angle (у радіанах). axis має бути нормалізованим вектором (див. Vector3.normalized()).

Додатні значення повертають цей базис за годинниковою стрілкою навколо осі, а від’ємні значення обертають його проти годинникової стрілки.

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

my_basis = my_basis.rotated(Vector3.UP, angle) # Обертання навколо осі вгору (yaw).
my_basis = my_basis.rotated(Vector3.RIGHT, angle) # Обертання навколо правої осі (крок).
my_basis = my_basis.rotated(Vector3.BACK, angle) # Обертання навколо задньої осі (перекочування).

Basis scaled(scale: Vector3) const 🔗

Повертає цю базу з компонентами кожної осі, масштабованими за заданими компонентами scale.

Рядки базової матриці множаться на компоненти scale. Ця операція має глобальний масштаб (щодо батьківської).

var my_basis = Основа(
     Vector3(1, 1, 1),Basis
     Vector3(2, 2, 2),
     Vector3(3, 3, 3)
 )
my_basis = my_basis.scaled(Vector3(0, 2, -2))

print(my_basis.x) # Виводить (0, 2, -2).
print(my_basis.y) # Виводить (0, 4, -4).
print(my_basis.z) # Виводить (0, 6, -6).

Basis scaled_local(scale: Vector3) const 🔗

Повертає цей basis, при цьому кожна вісь масштабується на відповідний компонент у заданому scale.

Стовпці базисної матриці множаться на компоненти scale. Ця операція є локальним масштабуванням (відносно себе).

[gdscript]
var my_basis = Basis(
Vector3(1, 1, 1),
Vector3(2, 2, 2),
Vector3(3, 3, 3)
)
my_basis = my_basis.scaled_local(Vector3(0, 2, -2))

print(my_basis.x) # Виводить (0.0, 0.0, 0.0)
print(my_basis.y) # Виводить (4.0, 4.0, 4.0)
print(my_basis.z) # Виводить (-6.0, -6.0, -6.0)
[/gdscript]
[csharp]
var myBasis = new Basis(
new Vector3(1.0f, 1.0f, 1.0f),
new Vector3(2.0f, 2.0f, 2.0f),
new Vector3(3.0f, 3.0f, 3.0f)
);
myBasis = myBasis.ScaledLocal(new Vector3(0.0f, 2.0f, -2.0f));

GD.Print(myBasis.X); // Виводить (0, 0, 0)
GD.Print(myBasis.Y); // Виводить (4, 4, 4)
GD.Print(myBasis.Z); // Виводить (-6, -6, -6)
[/csharp][/codeblocks]

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

Виконує сферично-лінійну інтерполяцію з основою to із заданою вагою weight. І цей базис, і to мають представляти обертання.

**Приклад: ** Плавно повертайте Node3D до цільової основи з часом за допомогою 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):

base = start_basis.slerp(target_basis, weight)

.. rst-class:: classref-item-separator

float tdotx(with: Vector3) const 🔗

Повертає транспонований скалярний добуток між with і віссю x (див. transponed()).

Це еквівалентно basis.x.dot(vector).


float tdoty(with: Vector3) const 🔗

Повертає транспонований скалярний добуток між with і віссю x (див. transponed()).

Це еквівалентно basis.x.dot(вектор).


float tdotz(with: Vector3) const 🔗

Повертає транспонований скалярний добуток між with і віссю z (див. transponed()).

Це еквівалентно basis.z.dot(vector).


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) # Виводить (1, 4, 7).
print(my_basis.y) # Виводить (2, 5, 8).
print(my_basis.z) # Виводить (3, 6, 9).

Описи операторів

bool operator !=(right: Basis) 🔗

Повертає true, якщо компоненти обох матриць Basis не рівні.

Примітка: Через помилки точності з плаваючою комою, краще використати is_equal_approx(), який є більш надійним.


Basis operator *(right: Basis) 🔗

Перетворює (множить) основу right на цю основу.

Це операція, яка виконується між батьківським і дочірнім Node3D.


Vector3 operator *(right: Vector3) 🔗

Перетворює (множить) вектор right на цю основу, повертаючи Vector3.

[gdscript]
 # Основа, яка змінює місцями осі 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, 2, 6)
[/gdscript]
[csharp]
 // Основа, яка змінює місцями осі X/Z і подвоює масштаб.
var myBasis = new basis (new vector3(0, 2, 0), new vector3(2, 0, 0), new vector3(0, 0, 2));
GD.Print(myBasis * new Vector3(1, 2, 3)); // Друкує (4, 2, 6)
[/csharp][/codeblocks]

Basis operator *(right: float) 🔗

Множить усі компоненти Basis на заданий float. Це рівномірно впливає на масштаб основи, змінюючи розмір усіх 3 осей на значення right.


Basis operator *(right: int) 🔗

Множить усі компоненти Basis на заданий int. Це рівномірно впливає на масштаб основи, змінюючи розмір усіх 3 осей на значення right.


Basis operator /(right: float) 🔗

Розділяє всі компоненти Basis на заданий float. Це рівномірно впливає на масштаб основи, змінюючи розмір усіх 3 осей на значення right.


Basis operator /(right: int) 🔗

Розділяє всі компоненти Basis на заданий int. Це рівномірно впливає на масштаб основи, змінюючи розмір усіх 3 осей на значення right.


bool operator ==(right: Basis) 🔗

Повертає true, якщо компоненти обох матриць Basis абсолютно рівні.

Примітка: Через помилки точності з плаваючою комою, краще використати is_equal_approx(), який є більш надійним.


Vector3 operator [](index: int) 🔗

Звертається до кожної осі (стовпця) цього базису за їхнім індексом. Індекс 0 такий самий, як x, індекс 1 такий самий, як y, а індекс 2 такий самий, як z.

Примітка: у C++ цей оператор звертається до рядків базисної матриці, а не до стовпців. Для такої самої поведінки, як і мови сценаріїв, використовуйте методи set_column і get_column.