Javascript 中的递归插值
Recursive Interpolation in Javascript
我正在开发一款网页游戏,其中包含多维度的三次插值。我需要获取一组值和一组坐标,并输出 nD space 中的点的估计值。我找到了一些很棒的一维三次插值教程,以及一些用 c++ 编写的 nD 三次插值示例(两者都是 here)。问题是这个c++代码使用了很多指针和位移位器,我认为JS没有。
一维三次插值很长,但是有兴趣的人看起来像这样:
f(a, b, c, d, x) = b + 0.5 * x*(c - a + x*(2*a - 5*b + 4*c - d + x*(3 *(b - c) + d - a))), 其中 a-d 是已知值,x 是 0 到 1 之间的值,它决定了点在 b 和 c 之间的相对位置
Js:
function interpolate(p, x){
return p[1] + 0.5 * x*(p[2] - p[0] + x*(2*p[0] - 5*p[1] + 4*p[2] - p[3] + x*(3*(p[1] - p[2]) + p[3] - p[0])));
}
二维插值可以像这样简单地实现:
g(a1, b1, c1, d1,a2,b2,c2,d2, a3, b3, c3, d3, a4, b4, c4, d4, x, y) =
f(f(a1, b1, c1, d1, y), f(a2, b2, c2, d2, y), f(a3, b3, c 3, d3, y), f(a4, b4 , c4, d4, y), x)
Js:
function interpolate2d(arr, x, y){
let a = [
interpolate(arr[0], y),
interpolate(arr[1], y),
interpolate(arr[2], y),
interpolate(arr[3], y),
];
return interpolate(a, x);
}
3d同理:
function interpolate3d(arr, x, y, z){
let a = [
interpolate2d(arr[0], y, z),
interpolate2d(arr[1], y, z),
interpolate2d(arr[2], y, z),
interpolate2d(arr[3], y, z)
];
return interpolate(a, x);
}
我是 Js 的新手,(刚从 c++ 和 java 转过来)并且不知道很多额外的功能。我没有在网上找到任何东西,除了 Array.reduce()
(不知道它如何处理嵌套数组)和上面 link 中的递归 C++ 代码:
double nCubicInterpolate (int n, double* p, double coordinates[]) {
assert(n > 0);
if (n == 1) {
return cubicInterpolate(p, *coordinates);
}
else {
double arr[4];
int skip = 1 << (n - 1) * 2;
arr[0] = nCubicInterpolate(n - 1, p, coordinates + 1);
arr[1] = nCubicInterpolate(n - 1, p + skip, coordinates + 1);
arr[2] = nCubicInterpolate(n - 1, p + 2*skip, coordinates + 1);
arr[3] = nCubicInterpolate(n - 1, p + 3*skip, coordinates + 1);
return cubicInterpolate(arr, *coordinates);
}
}
复制这个的 Js 函数是什么?
JavaScript 的翻译可以是:
function nCubicInterpolate(p, coordinates) {
if (coordinates.length == 1) {
return cubicInterpolate(p, coordinates[0]);
} else {
let fewerCoordinates = coordinates.slice(1);
let arr = p.map(hyperplane => nCubicInterpolate(hyperplane, fewerCoordinates));
return cubicInterpolate(arr, coordinates[0]);
}
}
请注意,JavaScript 中不需要参数 n
,因为 coordinates
数组参数的长度与其对应。 p
的嵌套级别也应与 n
相同。 JavaScript 没有编译时类型检查,因此自由在这里成为我们的优势:没有指针; p
是一个数组,但它可以是一个数字数组,或者是一个数字数组,或者...等等
为了完整起见,cubicInterpolate
函数与您在问题中指定的一样:
function cubicInterpolate(p, x) {
return p[1] + 0.5 * x*(p[2] - p[0] + x*(2*p[0] - 5*p[1] + 4*p[2] - p[3] + x*(3*(p[1] - p[2]) + p[3] - p[0])));
}
我正在开发一款网页游戏,其中包含多维度的三次插值。我需要获取一组值和一组坐标,并输出 nD space 中的点的估计值。我找到了一些很棒的一维三次插值教程,以及一些用 c++ 编写的 nD 三次插值示例(两者都是 here)。问题是这个c++代码使用了很多指针和位移位器,我认为JS没有。
一维三次插值很长,但是有兴趣的人看起来像这样:
f(a, b, c, d, x) = b + 0.5 * x*(c - a + x*(2*a - 5*b + 4*c - d + x*(3 *(b - c) + d - a))), 其中 a-d 是已知值,x 是 0 到 1 之间的值,它决定了点在 b 和 c 之间的相对位置
Js:
function interpolate(p, x){
return p[1] + 0.5 * x*(p[2] - p[0] + x*(2*p[0] - 5*p[1] + 4*p[2] - p[3] + x*(3*(p[1] - p[2]) + p[3] - p[0])));
}
二维插值可以像这样简单地实现:
g(a1, b1, c1, d1,a2,b2,c2,d2, a3, b3, c3, d3, a4, b4, c4, d4, x, y) =
f(f(a1, b1, c1, d1, y), f(a2, b2, c2, d2, y), f(a3, b3, c 3, d3, y), f(a4, b4 , c4, d4, y), x)
Js:
function interpolate2d(arr, x, y){
let a = [
interpolate(arr[0], y),
interpolate(arr[1], y),
interpolate(arr[2], y),
interpolate(arr[3], y),
];
return interpolate(a, x);
}
3d同理:
function interpolate3d(arr, x, y, z){
let a = [
interpolate2d(arr[0], y, z),
interpolate2d(arr[1], y, z),
interpolate2d(arr[2], y, z),
interpolate2d(arr[3], y, z)
];
return interpolate(a, x);
}
我是 Js 的新手,(刚从 c++ 和 java 转过来)并且不知道很多额外的功能。我没有在网上找到任何东西,除了 Array.reduce()
(不知道它如何处理嵌套数组)和上面 link 中的递归 C++ 代码:
double nCubicInterpolate (int n, double* p, double coordinates[]) {
assert(n > 0);
if (n == 1) {
return cubicInterpolate(p, *coordinates);
}
else {
double arr[4];
int skip = 1 << (n - 1) * 2;
arr[0] = nCubicInterpolate(n - 1, p, coordinates + 1);
arr[1] = nCubicInterpolate(n - 1, p + skip, coordinates + 1);
arr[2] = nCubicInterpolate(n - 1, p + 2*skip, coordinates + 1);
arr[3] = nCubicInterpolate(n - 1, p + 3*skip, coordinates + 1);
return cubicInterpolate(arr, *coordinates);
}
}
复制这个的 Js 函数是什么?
JavaScript 的翻译可以是:
function nCubicInterpolate(p, coordinates) {
if (coordinates.length == 1) {
return cubicInterpolate(p, coordinates[0]);
} else {
let fewerCoordinates = coordinates.slice(1);
let arr = p.map(hyperplane => nCubicInterpolate(hyperplane, fewerCoordinates));
return cubicInterpolate(arr, coordinates[0]);
}
}
请注意,JavaScript 中不需要参数 n
,因为 coordinates
数组参数的长度与其对应。 p
的嵌套级别也应与 n
相同。 JavaScript 没有编译时类型检查,因此自由在这里成为我们的优势:没有指针; p
是一个数组,但它可以是一个数字数组,或者是一个数字数组,或者...等等
为了完整起见,cubicInterpolate
函数与您在问题中指定的一样:
function cubicInterpolate(p, x) {
return p[1] + 0.5 * x*(p[2] - p[0] + x*(2*p[0] - 5*p[1] + 4*p[2] - p[3] + x*(3*(p[1] - p[2]) + p[3] - p[0])));
}