std::lerp
| ヘッダー <cmath> で定義 |
||
| (1) | ||
constexpr float lerp( float a, float b, float t ) noexcept; constexpr double lerp( double a, double b, double t ) noexcept; |
(C++20以降) (C++23まで) |
|
| constexpr /* floating-point-type */ lerp( /* floating-point-type */ a, |
(C++23から) | |
| ヘッダー <cmath> で定義 |
||
| template< class Arithmetic1, class Arithmetic2, class Arithmetic3 > constexpr /* common-floating-point-type */ |
(A) | (C++20以降) |
[0, 1) の範囲内にある場合、a と b の間の線形補間を計算します(それ以外の場合は線形外挿)。すなわち、浮動小数点計算の不正確さを考慮した a+t(b−a) の結果を計算します。 ライブラリは、パラメータ a、b、および t の型として、すべてのcv修飾なし浮動小数点型に対するオーバーロードを提供します。(C++23以降)目次 |
[編集] パラメータ
| a, b, t | - | 浮動小数点または整数値 |
[編集] 戻り値
a + t(b − a)
std::isfinite(a) && std::isfinite(b) が true の場合、以下の特性が保証されます。
- もし t == 0 ならば、結果は a と等しい。
- もし t == 1 ならば、結果は b と等しい。
- もし t >= 0 && t <= 1 ならば、結果は有限である。
- もし std::isfinite(t) && a == b ならば、結果は a と等しい。
- もし std::isfinite(t) || (b - a != 0 && std::isinf(t)) ならば、結果は NaN ではない。
CMP(x, y) を、x > y の場合は 1、x < y の場合は -1、それ以外の場合は 0 とします。任意の t1 と t2 に対して、以下の積は
- CMP(std::lerp(a, b, t2), std::lerp(a, b, t1)),
- CMP(t2, t1)、および
- CMP(b, a)
は非負である。(すなわち、std::lerp は単調である。)
[編集] 備考
追加のオーバーロードは、(A) とまったく同じように提供される必要はありません。それらは、最初の引数 num1、2番目の引数 num2、3番目の引数 num3 に対して、以下のことを保証するのに十分であるだけでよいです。
|
(C++23まで) |
|
もし num1、num2、num3 が算術型である場合、std::lerp(num1, num2, num3) は std::lerp(static_cast</*common-floating-point-type*/>(num1), そのような最高のランクとサブランクセを持つ浮動小数点型が存在しない場合、オーバーロード解決は提供されたオーバーロードから使用可能な候補を導出しません。 |
(C++23から) |
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_interpolate |
201902L |
(C++20) | std::lerp、 std::midpoint |
[編集] 例
#include <cassert> #include <cmath> #include <iostream> float naive_lerp(float a, float b, float t) { return a + t * (b - a); } int main() { std::cout << std::boolalpha; const float a = 1e8f, b = 1.0f; const float midpoint = std::lerp(a, b, 0.5f); std::cout << "a = " << a << ", " << "b = " << b << '\n' << "midpoint = " << midpoint << '\n'; std::cout << "std::lerp is exact: " << (a == std::lerp(a, b, 0.0f)) << ' ' << (b == std::lerp(a, b, 1.0f)) << '\n'; std::cout << "naive_lerp is exact: " << (a == naive_lerp(a, b, 0.0f)) << ' ' << (b == naive_lerp(a, b, 1.0f)) << '\n'; std::cout << "std::lerp(a, b, 1.0f) = " << std::lerp(a, b, 1.0f) << '\n' << "naive_lerp(a, b, 1.0f) = " << naive_lerp(a, b, 1.0f) << '\n'; assert(not std::isnan(std::lerp(a, b, INFINITY))); // lerp here can be -inf std::cout << "Extrapolation demo, given std::lerp(5, 10, t):\n"; for (auto t{-2.0}; t <= 2.0; t += 0.5) std::cout << std::lerp(5.0, 10.0, t) << ' '; std::cout << '\n'; }
実行結果の例
a = 1e+08, b = 1 midpoint = 5e+07 std::lerp is exact?: true true naive_lerp is exact?: true false std::lerp(a, b, 1.0f) = 1 naive_lerp(a, b, 1.0f) = 0 Extrapolation demo, given std::lerp(5, 10, t): -5 -2.5 0 2.5 5 7.5 10 12.5 15
[編集] 関連項目
| (C++20) |
2つの数値またはポインタの中間点 (関数テンプレート) |