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.
Посібники
Властивості
|
||
|
||
|
Конструктори
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 |
|
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 кутів Ейлера у радіанах.
# Створює основу, вісь 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 константи). За замовчуванням використовується конвенція 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 кутів Ейлера у радіанах. Для поверненого значення:
Vector3.x містить кут навколо осі х (крок);
Порядок кожного послідовного обертання можна змінити за допомогою 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. Якщо основа не зрізана, це коефіцієнт масштабування. На нього не впливає обертання.
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() на всіх векторних компонентах.
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.