Інтерполяція¶
Інтерполяція є самою базовою операцією в графічному програмуванні. Буде добре ознайомитися з нею, щоб розширити свій кругозір розробника графіки.
Основна ідея полягає в тому, що ви хочете перейти від А до В. Значення t
, представляє стани між ними.
Наприклад, якщо t
рівно 0, то стан рівний А. Якщо t
рівно 1, то стан рівний В. Всі проміжні стани називаються інтерполяцією.
Між двома дійсними (з десятковою комою) числами проста інтерполяція зазвичай описується як:
interpolation = A * (1 - t) + B * t
І часто спрощується до:
interpolation = A + (B - A) * t
Така інтерполяція, яка перетворює значення на інше з постійною швидкістю, називається "лінійною". Так що тепер, коли почуєте про Лінійну інтерполяцію, то будете знати, що мається на увазі ця проста формула.
Є й інші види інтерполяції, які тут не будуть розглядатися. Тому, після цієї статті, рекомендується прочитати сторінку Безьє.
Векторна інтерполяція¶
Векторні типи (Vector2 та Vector3) також можуть бути інтерпольовані, для цього вони мають зручні функції, Vector2.linear_interpolate() та Vector3.linear_interpolate().
Для кубічної інтерполяції існують також Vector2.cubic_interpolate() та Vector3.cubic_interpolate(), які виконують інтерполяцію в стилі Безьє.
Ось простий псевдокод для переходу з точки А в B за допомогою інтерполяції:
var t = 0.0
func _physics_process(delta):
t += delta * 0.4
$Sprite.position = $A.position.linear_interpolate($B.position, t)
private float _t = 0.0f;
public override void _PhysicsProcess(float delta)
{
_t += delta * 0.4f;
Position2D a = GetNode<Position2D>("A");
Position2D b = GetNode<Position2D>("B");
Sprite sprite = GetNode<Sprite>("Sprite");
sprite.Position = a.Position.LinearInterpolate(b.Position, _t);
}
Він буде виробляти наступний рух:
Інтерполяція перетворень¶
Також можна інтерполювати цілі перетворення (переконайтеся, що вони мають або рівномірний масштаб, або, принаймні, однаковий нерівномірний масштаб). Для цього можна використати функцію Transform.interpolate_with().
Ось приклад перетворення мавпочки з Позиції1 в Позицію2:
За допомогою наступного псевдокоду:
var t = 0.0
func _physics_process(delta):
t += delta
$Monkey.transform = $Position1.transform.interpolate_with($Position2.transform, t)
private float _t = 0.0f;
public override void _PhysicsProcess(float delta)
{
_t += delta;
Position3D p1 = GetNode<Position3D>("Position1");
Position3D p2 = GetNode<Position3D>("Position2");
CSGMesh monkey = GetNode<CSGMesh>("Monkey");
monkey.Transform = p1.Transform.InterpolateWith(p2.Transform, _t);
}
Він буде виробляти наступний рух:
Плавний рух¶
Інтерполяція може бути використана для створення плавного руху, обертання та ін. Ось приклад кола, що переслідує мишку за допомогою плавного руху:
const FOLLOW_SPEED = 4.0
func _physics_process(delta):
var mouse_pos = get_local_mouse_position()
$Sprite.position = $Sprite.position.linear_interpolate(mouse_pos, delta * FOLLOW_SPEED)
private const float FollowSpeed = 4.0f;
public override void _PhysicsProcess(float delta)
{
Vector2 mousePos = GetLocalMousePosition();
Sprite sprite = GetNode<Sprite>("Sprite");
sprite.Position = sprite.Position.LinearInterpolate(mousePos, delta * FollowSpeed);
}
Ось як це виглядає:
Це корисно для згладжування руху камери, союзників, що йдуть за вами (гарантуючи, що вони залишаються в межах певного діапазону), і багатьох інших поширених моделей гри.