最終更新日時(UTC):
が更新

履歴 編集

function
<cmath>

std::lerp(C++20)

namespace std {
  constexpr float lerp(float a, float b, float t) noexcept;
  constexpr double lerp(double a, double b, double t) noexcept;
  constexpr long double lerp(long double a, long double b, long double t) noexcept;
}

概要

二点abの間を、時間tで線形補間 (linear interpolate) する。

時間は 0.0 (0%) から 1.0 (100%) までの値を基本的には指定するが、1.0を超える指定も許可されている。

この関数を使用することによって、現在位置を少しずつ進めていくプログラミングスタイルから、現在位置と目標位置を最初に決めて現在の時間に対応する位置を求めるというプログラミングスタイルに考え方を変更できる。

戻り値

return a + t * (b - a);

例外

投げない

備考

  • isfinite(a) && isfinite(b)である場合、戻り値rは以下のようになる:
    • t == 0である場合、r == a
    • t == 1である場合、r == b
    • t >= 0 && t <= 1である場合、isfinite(r) != 0
    • isfinite(t) && a == bである場合、r == a
    • isfinite(t) || !isnan(t) && b - a != 0である場合、!isnan(r)
  • 比較関数CMP(x, y)を、x > yであれば1、x < yであれば-1、そうでなければ0を返すものであるとして、あらゆる時間値t1t2についてCMP(lerp(a,b,t2), lerp(a,b,t1))CMP(t2, t1)CMP(b,a)はいずれも非負となる

基本的な使い方

#include <iostream>
#include <cmath>

int main()
{
  // 開始点0.0から、目標点10.0まで、10% (時間0.1) ずつ値を進める
  float start = 0.0f;
  float target = 10.0f;

  float t = 0.0f;
  for (int i = 0; i <= 10; ++i) {
    float r = std::lerp(start, target, t);
    std::cout << r << std::endl;

    t += 0.1f;
  }
}

出力

0
1
2
3
4
5
6
7
8
9
10

2次元上の二点間で線形補間する

#include <iostream>
#include <cmath>

// 2次元上の点を表す型
struct Point {
  float x, y;
};

// Point型用に線形補間の機能を定義する
Point lerp(const Point& a, const Point& b, float t)
{
  return Point{
    std::lerp(a.x, b.x, t),
    std::lerp(a.y, b.y, t)
  };
}

int main()
{
  const Point a{1.0f, 2.0f};
  const Point b{5.0f, 3.0f};

  // 点aから点bに向かって、10%ずつ位置を進める
  float t = 0.1f;
  for (int i = 0; i <= 10; ++i) {
    const Point p = lerp(a, b, t);
    std::cout << t << " : (" << p.x << ", " << p.y << ')' << std::endl;

    t += 0.1f;
  }
}

出力

0.1 : (1.4, 2.1)
0.2 : (1.8, 2.2)
0.3 : (2.2, 2.3)
0.4 : (2.6, 2.4)
0.5 : (3, 2.5)
0.6 : (3.4, 2.6)
0.7 : (3.8, 2.7)
0.8 : (4.2, 2.8)
0.9 : (4.6, 2.9)
1 : (5, 3)
1.1 : (5.4, 3.1)

バージョン

言語

  • C++20

処理系

関連項目

参照