Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Basis
Матриця 3×3 для представлення тривимірного обертання та масштабу.
Опис
Вбудований тип Basis Variant — це матриця розміром 3×3, яка використовується для представлення 3D-обертання, масштабування та зсуву. Вона часто застосовується в об’єкті Transform3D.
Basis складається з 3 векторів осей, кожен з яких представляє стовпець матриці: x, y та z. Довжина кожної осі (Vector3.length()) впливає на масштаб базису, тоді як напрямок усіх осей впливає на обертання. Зазвичай ці осі перпендикулярні одна до одної. Однак, коли ви обертаєте будь-яку вісь окремо, базис зазнає зсуву. Застосування зсунутого базису до 3D-моделі призведе до спотворення моделі.
Basis є:
Ортогональним, якщо його осі перпендикулярні одна до одної.
Нормованим, якщо довжина кожної осі дорівнює
1.0.Однорідною, якщо всі осі мають однакову довжину (див.
метод get_scale).Ортонормованою, якщо вона є одночасно ортогональною та нормалізованою, що дозволяє їй відображати лише обертання (див.
метод orthonormalized).Конформна, якщо вона є одночасно ортогональною та рівномірною, що гарантує відсутність спотворень.
Загальне введення дивіться у підручнику Матриці та перетворення.
Примітка: Godot використовує праворучну систему координат, що є загальноприйнятим стандартом. Щодо напрямків, у вбудованих типах, таких як Camera3D, прийнято, що вісь -Z спрямована вперед (+X — праворуч, +Y — вгору, а +Z — назад). Інші об'єкти можуть використовувати інші угоди щодо напрямків. Для отримання додаткової інформації дивіться підручник Угоди щодо напрямків 3D-ресурсів.
Примітка: Матриці бази представлені у порядку column-major, що відповідає OpenGL. Однак внутрішньо вони зберігаються у порядку row-major, що відповідає DirectX.
Примітка: У булевому контексті базис буде обчислюватися як false, якщо він дорівнює IDENTITY. В іншому випадку базис завжди обчислюватиметься як true.
Примітка
Існують значні відмінності при використанні цього API із С#. Більше інформації: ref:doc_c_sharp_differences.
Посібники
Властивості
|
||
|
||
|
Конструктори
Basis() |
|
Basis(from: Quaternion) |
|
Методи
determinant() const |
|
from_euler(euler: Vector3, order: int = 2) static |
|
from_scale(scale: Vector3) static |
|
get_rotation_quaternion() const |
|
get_scale() const |
|
inverse() const |
|
is_conformal() const |
|
is_equal_approx(b: Basis) const |
|
is_finite() const |
|
is_orthonormal() const |
|
looking_at(target: Vector3, up: Vector3 = Vector3(0, 1, 0), use_model_front: bool = false) static |
|
orthonormalized() const |
|
scaled_local(scale: Vector3) const |
|
transposed() const |
Оператори
operator !=(right: Basis) |
|
operator *(right: Basis) |
|
operator *(right: Vector3) |
|
operator *(right: float) |
|
operator *(right: int) |
|
operator /(right: float) |
|
operator /(right: int) |
|
operator ==(right: Basis) |
|
operator [](index: int) |
Константи
IDENTITY = Basis(1, 0, 0, 0, 1, 0, 0, 0, 1) 🔗
Ідентичність Основа. Це ортонормований базис без обертання, без зсуву та масштабом Vector3.ONE. Це також означає, що:
x вказує праворуч (Vector3.RIGHT);
y вказує вгору (Vector3.UP);
z вказує назад (Vector3.BACK).
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_Y = Basis(1, 0, 0, 0, -1, 0, 0, 0, 1) 🔗
Коли будь-який базис множиться на FLIP_Y, він заперечує всі компоненти осі y (стовпець Y).
FLIP_Z = Basis(1, 0, 0, 0, 1, 0, 0, 0, -1) 🔗
Коли будь-який базис множиться на FLIP_Z, він заперечує всі компоненти осі 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, ідентичний IDENTITY.
Примітка: у C# це створює Basis з усіма його компонентами, встановленими на Vector3.ZERO.
Створює 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-х осьових векторів. Це стовпці базисної матриці.
Описи методів
Повертає визначник матриці цієї бази. Для просунутої математики це число може бути використане для визначення декількох атрибутів:
Якщо визначник дорівнює точно
0.0, база не є оберненою (див. inverse()).Якщо визначник є від'ємним числом, основа представляє від'ємну шкалу.
Примітка: Якщо шкала основи однакова для кожної осі, її визначник завжди дорівнює цій шкалі, піднесеної до степеня 3.
Basis from_euler(euler: Vector3, order: int = 2) static 🔗
Створює новий об’єкт Basis, який відображає лише обертання навколо заданого Vector3 з кутів Ейлера у радіанах.
# Створює Basis, вісь z якого спрямована вниз.
var my_basis = Basis.from_euler(Vector3(TAU / 4, 0, 0))
print(my_basis.z) # Виводить (0.0, -1.0, 0.0)
// Створює базис, вісь z якого спрямована вниз.
var myBasis = Basis.FromEuler(new Vector3(Mathf.Tau / 4.0f, 0.0f, 0.0f));
GD.Print(myBasis.Z); // Виводить (0, -1, 0)
Порядок кожного послідовного обертання можна змінити за допомогою order (див. константи EulerOrder). У Godot кути Ейлера завжди використовують внутрішній порядок. За замовчуванням використовується внутрішня конвенція 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).
var myBasis = Basis.FromScale(new Vector3(2.0f, 4.0f, 8.0f));
GD.Print(myBasis.X); // Виводить (2, 0, 0).
GD.Print(myBasis.Y); // Виводить (0, 4, 0).
GD.Print(myBasis.Z); // Виводить (0, 0, 8).
Примітка. У лінійній алгебрі матриця цього базису також відома як діагональна матриця.
Vector3 get_euler(order: int = 2) const 🔗
Повертає обертання цієї бази у вигляді Vector3 з кутами Ейлера у радіанах. Щодо повернутого значення:
Порядок кожного послідовного обертання можна змінити за допомогою order (див. константи EulerOrder). У Godot кути Ейлера завжди використовують внутрішній порядок. За замовчуванням використовується внутрішня конвенція 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. Якщо основа не зрізана, це коефіцієнт масштабування. На нього не впливає обертання.
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).
var myBasis = new Basis(
Vector3(2.0f, 0.0f, 0.0f),
Vector3(0.0f, 4.0f, 0.0f),
Vector3(0.0f, 0.0f, 8.0f)
);
// Обертання основи будь-яким способом зберігає її масштаб.
myBasis = myBasis.Rotated(Vector3.Up, Mathf.Tau / 2.0f);
myBasis = myBasis.Rotated(Vector3.Right, Mathf.Tau / 4.0f);
GD.Print(myBasis.Scale); // Виводить (2, 4, 8).
Примітка. Якщо значення, яке повертає determinant(), є негативним, шкала також є негативною.
Повертає обернену до базисної матриці.
Повертає true, якщо цей базис конформний. Конформна основа є як ортогональною (осі перпендикулярні одна до одної), так і однорідною (осі мають однакову довжину). Цей метод може бути особливо корисним під час фізичних розрахунків.
bool is_equal_approx(b: Basis) const 🔗
Повертає true, якщо ця основа та b приблизно рівні, шляхом виклику @GlobalScope.is_equal_approx() для всіх компонентів вектора.
Повертає true, якщо ця основа скінченна, за викликом @GlobalScope.is_finite() на всіх векторних компонентах.
Повертає true, якщо цей базис є ортонормальним. Ортонормальний базис є одночасно ортогональним (осі перпендикулярні одна до одної) та нормалізованим (довжина кожної осі дорівнює 1.0). Цей метод може бути особливо корисним під час фізичних розрахунків.
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()
// Обертати цей Node3D кожен кадр.
public override void _Process(double delta)
{
Basis = Basis.Rotated(Vector3.Up, Mathf.Tau * (float)delta)
.Rotated(Vector3.Right, Mathf.Tau * (float)delta)
.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) # Обертання навколо задньої осі (перекочування).
var myBasis = Basis.Identity;
var angle= Mathf.Tau / 2.0f;
myBasis = myBasis.Rotated(Vector3.Up, кут); // Обертання навколо осі вгору (рискання).
myBasis = myBasis.Rotated(Vector3.Right, angle); // Поворот навколо правої осі (тангаж).
myBasis = myBasis.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).
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.Scaled(new Vector3(0.0f, 2.0f, -2.0f));
GD.Print(myBasis.X); // Виводить (0, 2, -2).
GD.Print(myBasis.Y); // Виводить (0, 4, -4).
GD.Print(myBasis.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).
Повертає транспоновану версію цієї основи. Це перетворює стовпці базової матриці на рядки, а її рядки – на стовпці.
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).
var myBasis = new Basis(
new Vector3 (1.0f, 2.0f, 3.0f),
new Vector3 (4.0f, 5.0f, 6.0f),
new Vector3 (7.0f, 8.0f, 9.0f)
);
myBasis = myBasis.Transposed();
GD.Print(myBasis.X); // Виводить (1, 4, 7).
GD.Print(myBasis.Y); // Виводить (2, 5, 8).
GD.Print(myBasis.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.