Basis
Une matrice 3×3 pour représenter une rotation et une échelle 3D.
Description
Le type Variant intégré Basis (litt. Base) est une matrice 3×3 utilisée pour représenter une rotation, échelle et cisaillement 3D. Il est fréquemment utilisé dans un Transform3D.
Une Basis est composé de 3 axes vectoriels, chacun représentant une colonne de la matrice : x, y, et z. La longueur de chaque axe (Vector3.length()) influence l'échelle de base, tandis que la direction de tous les axes influence la rotation. Habituellement, ces axes sont perpendiculaires les uns aux autres. Cependant, lorsque vous tournez n'importe quel axe individuellement, la base devient cisaillée. L'application d'une base cisaillée à un modèle 3D fera apparaître le modèle comme déformé.
Une Basis est :
Orthogonale si ses axes sont perpendiculaires les uns aux autres.
Normalisée si la longueur de chaque axe vaut
1.0.Uniforme si tous les axes partagent la même longueur (voir get_scale()).
Orthonormael si elle est à la fois orthogonale et normalisée, ce qui lui permet de ne représenter que des rotations (voir orthonormalized()).
Conforme si elle est à la fois orthogonale et uniforme, ce qui assure qu'elle n'est pas déformée.
Pour une introduction générale, voir le tutoriel Matrices et transformations.
Note : Godot utilise un système de coordonnées main-droite, qui est une norme habituelle. Pour les directions, la convention pour les types intégrés comme Camera3D est que -Z pointe vers l'avant (+X vers la droite, +Y vers le haut, et +Z vers l'arrière). D'autres objets peuvent utiliser des conventions de direction différentes. Pour plus d'informations, voir le tutoriel Conventions de direction de ressource 3D.
Note : Les matrices de base sont exposées dans l'ordre column-major (par colonnes), qui est le même qu'OpenGL. Cependant, elles sont stockées en interne dans l'ordre row-major (par lignes), qui est le même que DirectX.
Note
Il y a des différences notables dans l'utilisation de cette API en C#. Voir Différences de l'API C# par rapport à GDScript pour plus d'informations.
Tutoriels
Propriétés
|
||
|
||
|
Constructeurs
Basis() |
|
Basis(from: Quaternion) |
|
Méthodes
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 |
Opérateurs
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) |
Constantes
IDENTITY = Basis(1, 0, 0, 0, 1, 0, 0, 0, 1) 🔗
La Basis identité. Il s'agit d'une base orthonormée sans rotation, sans cisaillement, et d'une échelle de Vector3.ONE. Cela signifie également que :
Le x pointe vers la droite (Vector3.RIGHT);
Le y pointe vers le haut (Vector3.UP);
Le z pointe vers l'arrière (Vector3.BACK).
var base = Basis.IDENTITY
print("| X | Y | Z")
print("| %.f | %.f | %.f" % [base.x.x, base.y.x, base.z.x])
print("| %.f | %.f | %.f" % [base.x.y, base.y.y, base.z.y])
print("| %.f | %.f | %.f" % [base.x.z, base.y.z, base.z.z])
# Affiche :
# | X | Y | Z
# | 1 | 0 | 0
# | 0 | 1 | 0
# | 0 | 0 | 1
Si un Vector3 ou une autre Basis est transformé (multiplié) par cette constante, aucune transformation ne se produit.
Note : En GDScript, cette constante est équivalente à la création d'un Basis sans aucun argument. Elle peut être utilisée pour rendre votre code plus clair, et pour la cohérence avec le C#.
FLIP_X = Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1) 🔗
Lorsqu'une base est multipliée par FLIP_X, cela inverse le signe toutes les composantes de l'axe x (la colonne X).
Lorsque FLIP_X est multiplié par n'importe quelle base, cela inverse le signe de la composante Vector3.x de tous les axes (la ligne X).
FLIP_Y = Basis(1, 0, 0, 0, -1, 0, 0, 0, 1) 🔗
Lorsqu'une base est multipliée par FLIP_Y, cela inverse le signe toutes les composantes de l'axe y (la colonne Y).
Lorsque FLIP_Y est multiplié par n'importe quelle base, cela inverse le signe de la composante Vector3.y de tous les axes (la ligne Y).
FLIP_Z = Basis(1, 0, 0, 0, 1, 0, 0, 0, -1) 🔗
Lorsqu'une base est multipliée par FLIP_Z, cela inverse le signe toutes les composantes de l'axe z (la colonne Z).
Lorsque FLIP_Z est multiplié par n'importe quelle base, cela inverse le signe de la composante Vector3.z de tous les axes (la ligne Z).
Descriptions des propriétés
Vector3 x = Vector3(1, 0, 0) 🔗
L'axe X de la base et la colonne 0 de la matrice.
Sur la base identité, ce vecteur pointe vers la droite (Vector3.RIGHT).
Vector3 y = Vector3(0, 1, 0) 🔗
L'axe Y de la base et la colonne 1 de la matrice.
Sur la base identité, ce vecteur pointe vers le haut (Vector3.UP).
Vector3 z = Vector3(0, 0, 1) 🔗
L'axe Z de la base et la colonne 2 de la matrice.
Sur la base identité, ce vecteur pointe vers l'arrière (Vector3.BACK).
Descriptions des constructeurs
Construit une Basis identique à IDENTITY.
Note : En C#, cela construit une Basis avec tous ses composantes définies à Vector3.ZERO.
Construit une Basis en tant que copie de la Basis donnée.
Basis Basis(axis: Vector3, angle: float)
Construit une Basis qui ne représente qu'une rotation, tournant autour de l'axe axis d'un angle angle donné, en radians. L'axe doit être un vecteur normalisé.
Note : C'est identique à l'utilisation de rotated() sur la base IDENTITY. Avec plus d'un angle, considérez à la place d'utiliser from_euler().
Basis Basis(from: Quaternion)
Construit une Basis qui ne représente seulement qu'une rotation d'un Quaternion donné.
Note: Les quaternions ne stockent seulement que des rotations, pas d'échelle. À cause de cela, les conversions de Basis vers Quaternion ne peuvent pas toujours être inversées.
Basis Basis(x_axis: Vector3, y_axis: Vector3, z_axis: Vector3)
Construit une Basis à partir de 3 vecteurs d'axe. Ce sont les colonnes de la matrice de la base.
Descriptions des méthodes
Renvoie le déterminant de la matrice de cette base. Pour les mathématiques avancées, ce nombre peut être utilisé pour déterminer quelques attributs :
Si le déterminant vaut exactement
0.0, la base n'est pas inversible (voir inverse()).Si le déterminant est un nombre négatif, la base représente une échelle négative.
Note : Si l'échelle de la base est la même pour chaque axe, son déterminant vaut toujours cette échelle à la puissance 3.
Basis from_euler(euler: Vector3, order: int = 2) static 🔗
Construit une nouvelle Basis qui ne représente que la rotation du Vector3 d'angles d'Euler donnés, en radians.
Le Vector3.x devrait contenir l'angle autour de l'axe x (roulis);
Le Vector3.y devrait contenir l'angle autour de l'axe y (tangage);
Le Vector3.z devrait contenir l'angle autour de l'axe z (lacet).
# Crée une Basis dont l'axe z pointe vers le bas.
var ma_base = Basis.from_euler(Vector3(TAU / 4, 0, 0))
print(ma_base.z) # Affiche (0.0, -1.0, 0.0)
// Crée une Basis dont l'axe z pointe vers le bas.
var maBase = Basis.FromEuler(new Vector3(Mathf.Tau / 4.0f, 0.0f, 0.0f));
GD.Print(maBase.Z); // Affiche (0, -1, 0)
L'ordre de chaque rotation consécutive peut être modifié avec le paramètre order (voir les constantes EulerOrder). Par défaut, la convention YXZ est utilisée (@GlobalScope.EULER_ORDER_YXZ) : la base tourne d'abord autour de l'axe Y (tangage), puis X (roulis) et enfin Z (lacet). En utilisant la méthode opposée get_euler(), cet ordre est inversé.
Basis from_scale(scale: Vector3) static 🔗
Construit une nouvelle Basis qui ne représente qu'une échelle, sans rotation ni cisaillement, depuis le vecteur scale donné.
var ma_base = Basis.from_scale(Vector3(2, 4, 8))
print(ma_base.x) # Affiche (2.0, 0.0, 0.0)
print(ma_base.y) # Affiche (0.0, 4.0, 0.0)
print(ma_base.z) # Affiche (0.0, 0.0, 8.0)
var maBase = Basis.FromScale(new Vector3(2.0f, 4.0f, 8.0f));
GD.Print(maBase.X); // Affiche (2, 0, 0)
GD.Print(maBase.Y); // Affiche (0, 4, 0)
GD.Print(maBase.Z); // Affiche (0, 0, 8)
Note : En algèbre linéaire, la matrice de cette base est également connue sous le nom de matrice diagonale.
Vector3 get_euler(order: int = 2) const 🔗
Renvoie la rotation de cette base en tant que Vector3 d'angles d'Euler, en radians. Pour la valeur renvoyée :
L'ordre de chaque rotation consécutive peut être modifié avec le paramètre order (voir les constantes EulerOrder). Par défaut, la convention YXZ est utilisée (@GlobalScope.EULER_ORDER_YXZ) : la base tourne d'abord autour de l'axe Y (tangage), puis X (roulis) et enfin Z (lacet). En utilisant la méthode opposée get_euler(), cet ordre est inversé.
Note : Pour que cette méthode puisse renvoyer correctement, la base doit être orthonormale (voir orthonormalized()).
Note : Les angles d'Euler sont beaucoup plus intuitifs mais ne conviennent pas aux maths en 3D. Pour cette raison, envisagez d'utiliser la méthode get_rotation_quaternion() qui renvoie un Quaternion.
Note : Dans le dock de l'inspecteur, la rotation d'une base est souvent affichée en angles d'Euler (en degrés), comme c'est le cas avec la propriété Node3D.rotation.
Quaternion get_rotation_quaternion() const 🔗
Renvoie la rotation de cette base en tant que Quaternion.
Note : Les quaternions sont beaucoup plus adaptés aux maths en 3D mais sont moins intuitifs. Pour les interfaces utilisateur, envisagez d'utiliser la méthode get_euler() qui renvoie des angles d'Euler.
Renvoie la longueur de chaque axe de cette base, en tant que Vector3. Si la base n'est pas cisaillée, cette valeur est le facteur d'échelle. Il n'est pas affecté par la rotation.
var ma_base = Basis(
Vector3(2, 0, 0),
Vector3(0, 4, 0),
Vector3(0, 0, 8)
)
# Tourner la Basis de n'importe quelle façon conserve son échelle.
ma_base = ma_base.rotated(Vector3.UP, TAU / 2)
ma_base = ma_base.rotated(Vector3.RIGHT, TAU / 4)
print(my_basis.get_scale()) # Affiche (2.0, 4.0, 8.0)
var maBase = new Basis(
Vector3(2.0f, 0.0f, 0.0f),
Vector3(0.0f, 4.0f, 0.0f),
Vector3(0.0f, 0.0f, 8.0f)
);
//Tourner la Basis de n'importe quelle façon conserve son échelle.
maBase = maBase.Rotated(Vector3.Up, Mathf.Tau / 2.0f);
maBase = maBase.Rotated(Vector3.Right, Mathf.Tau / 4.0f);
GD.Print(maBase.Scale); // Affiche (2, 4, 8)
Note : Si la valeur renvoyée par determinant() est négative, l'échelle est également négative.
Renvoie l'inverse de la matrice de cette base.
Renvoie true si cette base est conforme. Une base conforme est à la fois orthogonale (les axes sont perpendiculaires les uns aux autres) et uniforme (les axes partagent la même longueur). Cette méthode peut être particulièrement utile lors des calculs de physique.
bool is_equal_approx(b: Basis) const 🔗
Renvoie true si cette base et b sont approximativement égales, en appelant @GlobalScope.is_equal_approx() sur toutes les composantes vectorielles.
Renvoie true si cette base est finie, en appelant @GlobalScope.is_finite() sur toutes les composantes vectorielles.
Basis looking_at(target: Vector3, up: Vector3 = Vector3(0, 1, 0), use_model_front: bool = false) static 🔗
Crée une nouvelle Basis avec une rotation telle que l'axe avant (-Z) pointe vers la position target.
Par défaut, l'axe -Z (avant de la caméra) est traité comme l'avant (implique +X est la droite). Si use_model_front vaut true, l'axe +Z (axe avant des ressources) est traité comme l'avant (implique +X est la gauche) et pointe vers la position target.
L'axe vers le haut (+Y) pointe aussi près du vecteur up que possible tout en restant perpendiculaire à l'axe avant. La base renvoyée est orthonormalisée (voir orthonormalized()).
La cible target et le vecteur haut up ne peuvent être Vector3.ZERO, et ne devraient pas être colinéaires afin d'éviter une rotation inattendue autour de l'axe Z local.
Basis orthonormalized() const 🔗
Renvoie la version orthonormalisée de cette base. Une base orthonormale est à la fois orthogonale (les axes sont perpendiculaires les uns aux autres) et normalisée (les axes ont une longueur de 1.0), ce qui signifie également qu'elle ne peut représenter qu'une rotation.
Il est souvent utile d'appeler cette méthode pour éviter les erreurs d'arrondissement sur une base tournante :
# Tourner ce Node3D à chaque trame.
func _process(delta):
base = base.rotated(Vector3.UP, TAU * delta)
base = base.rotated(Vector3.RIGHT, TAU * delta)
base = base.orthonormalized()
// Tourner ce Node3D à chaque trame.
public override void _Process(double delta)
{
Base = Base.Rotated(Vector3.Up, Mathf.Tau * (float)delta)
.Rotated(Vector3.Right, Mathf.Tau * (float)delta)
.Orthonormalized();
}
Basis rotated(axis: Vector3, angle: float) const 🔗
Renvoie une copie de cette base tournée autour de l'axe axis donné de l'angle angle donné (en radians).
L'axe axis doit être un vecteur normalisé (voir Vector3.normalized()). Si angle est positif, la base est orientée dans le sens horaire inverse autour de l'axe.
var ma_base = Basis.IDENTITY
var angle = TAU / 2
ma_base = ma_base.rotated(Vector3.UP, angle) # Tourner autour de l'axe du haut (Roulis).
ma_base = ma_base.rotated(Vector3.RIGHT, angle) # Tourner autour de l'axe de droite (Tangage).
ma_base = ma_base.rotated(Vector3.BACK, angle) # Tourner autour de l'axe arrière (Lacet).
var maBase = Basis.Identity;
var angle = Mathf.Tau / 2.0f;
maBase = maBase.Rotated(Vector3.Up, angle); // Tourner autour de l'axe du haut (Roulis).
maBase = maBase.Rotated(Vector3.Droit, angle); // Tourner autour de l'axe de droite (Tangage).
maBase = maBase.Rotated(Vector3.Back, angle); // Tourner autour de l'axe arrière (Lacet).
Basis scaled(scale: Vector3) const 🔗
Renvoie cette base avec les composantes de chaque axe redimensionnés par les composantes de scale.
Les lignes de la matrice de la base sont multipliées par les composants de scale. Cette opération est une échelle globale (relative au parent).
var ma_base = Basis(
Vector3(1, 1, 1),
Vector3(2, 2, 2),
Vector3(3, 3, 3)
)
ma_base = ma_base.scaled(Vector3(0, 2, -2))
print(ma_base.x) # Affiche (0.0, 2.0, -2.0)
print(ma_base.y) # Affiche (0.0, 4.0, -4.0)
print(ma_base.z) # Affiche (0.0, 6.0, -6.0)
var maBase = 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)
);
maBase = maBase.Scaled(new Vector3(0.0f, 2.0f, -2.0f));
GD.Print(maBase.X); // Affiche (0, 2, -2)
GD.Print(maBase.Y); // Affiche (0, 4, -4)
GD.Print(maBase.Z); // Affiche (0, 6, -6)
Basis scaled_local(scale: Vector3) const 🔗
Renvoie cette base avec les composantes de chaque axe redimensionnées par les composantes correspondantes de l'échelle scale donnée.
Les colonnes de la matrice de la base sont multipliées par les composantes de scale. Cette opération est une échelle locale (relative à elle même).
var ma_base = Basis(
Vector3(1, 1, 1),
Vector3(2, 2, 2),
Vector3(3, 3, 3)
)
ma_base = ma_base.scaled_local(Vector3(0, 2, -2))
print(ma_base.x) # Affiche (0.0, 0.0, 0.0)
print(ma_base.y) # Affiche (4.0, 4.0, 4.0)
print(ma_base.z) # Affiche (-6.0, -6.0, -6.0)
var maBase = 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)
);
maBase = maBase.ScaledLocal(new Vector3(0.0f, 2.0f, -2.0f));
GD.Print(maBase.X); // Affiche (0, 0, 0)
GD.Print(maBase.Y); // Affiche (4, 4, 4)
GD.Print(maBase.Z); // Affiche (-6, -6, -6)
Basis slerp(to: Basis, weight: float) const 🔗
Effectue une interpolation sphérique-linéaire avec la base to, selon un poids weight donné. Cette base et to devraient tous deux représenter une rotation.
Exemple : Tourner de manière lisse un Node3D vers la base cible au fil du temps, avec un Tween :
var base_depart = Basis.IDENTITY
var base_cible = Basis.IDENTITY.rotated(Vector3.UP, TAU / 2)
func _ready():
create_tween().tween_method(interpoler, 0.0, 1.0, 5.0).set_trans(Tween.TRANS_EXPO)
func interpoler(poids):
base = base_depart.slerp(base_cible, poids)
float tdotx(with: Vector3) const 🔗
Renvoie le produit scalaire transposé entre with et l'axe x (voir transposed()).
Ceci est équivalent à base.x.dot(vecteur).
float tdoty(with: Vector3) const 🔗
Renvoie le produit scalaire transposé entre with et l'axe y (voir transposed()).
Ceci est équivalent à base.y.dot(vecteur).
float tdotz(with: Vector3) const 🔗
Renvoie le produit scalaire transposé entre with et l'axe z (voir transposed()).
Ceci est équivalent à base.z.dot(vecteur).
Renvoie la version transposée de cette base. Cela transforme les colonnes de la matrice de base en lignes, et ses lignes en colonnes.
var ma_base = Basis(
Vector3(1, 2, 3),
Vector3(4, 5, 6),
Vector3(7, 8, 9)
)
ma_base = ma_base.transposed()
print(ma_base.x) # Affiche (1.0, 4.0, 7.0)
print(ma_base.y) # Affiche (2.0, 5.0, 8.0)
print(ma_base.z) # Affiche (3.0, 6.0, 9.0)
var maBase = 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)
);
maBase = maBase.Transposed();
GD.Print(maBase.X); // Affiche (1, 4, 7)
GD.Print(maBase.Y); // Affiche (2, 5, 8)
GD.Print(maBase.Z); // Affiche (3, 6, 9)
Descriptions des opérateurs
bool operator !=(right: Basis) 🔗
Renvoie true si les composantes des deux matrices Basis ne sont pas égales.
Note : À cause des erreurs de précision des flottants, envisagez d'utiliser is_equal_approx() à la place, qui est plus fiable.
Basis operator *(right: Basis) 🔗
Transforme (multiplie) la base right par cette base.
C'est l'opération effectuée entre les Node3D parent et enfant.
Vector3 operator *(right: Vector3) 🔗
Transforme (multiplie) le vecteur right par cette base, renvoyant un Vector3.
# Basis qui échange les axes X/Z et double l'échelle.
var ma_base = Basis(Vector3(0, 2, 0), Vector3(2, 0, 0), Vector3(0, 0, 2))
print(ma_base * Vector3(1, 2, 3)) # Affiche (4.0, 2.0, 6.0)
// Basis qui échange les axes X/Z et double l'échelle.
var maBase = new Basis(new Vector3(0, 2, 0), new Vector3(2, 0, 0), new Vector3(0, 0, 2));
GD.Print(maBase * new Vector3(1, 2, 3)); // Affiche (4, 2, 6)
Basis operator *(right: float) 🔗
Multiplie toutes les composantes de la Basis par le float donné. Cela affecte uniformément l'échelle de la base, redimensionnant les 3 axes par la valeur right.
Basis operator *(right: int) 🔗
Multiplie toutes les composantes de la Basis par le int donné. Cela affecte uniformément l'échelle de la base, redimensionnant les 3 axes par la valeur right.
Basis operator /(right: float) 🔗
Divise toutes les composantes de la Basis par le float donné. Cela affecte uniformément l'échelle de la base, redimensionnant les 3 axes par la valeur right.
Basis operator /(right: int) 🔗
Divise toutes les composantes de la Basis par le int donné. Cela affecte uniformément l'échelle de la base, redimensionnant les 3 axes par la valeur right.
bool operator ==(right: Basis) 🔗
Renvoie true si les composantes des deux matrices Basis sont exactement égales.
Note : À cause des erreurs de précision des flottants, envisagez d'utiliser is_equal_approx() à la place, qui est plus fiable.
Vector3 operator [](index: int) 🔗
Accède à chaque axe (colonne) de cette base par leur index. L'index 0 est comme x, l'index 1 est comme y, et l'index 2 est le même que z.
Note : En C++, cet opérateur accède aux lignes de la matrice de la base, pas les colonnes. Pour le même comportement que les languages de script, utilisez les méthodes set_column et get_column.