拉伸数组

发布于 2024-09-11 01:20:11 字数 154 浏览 3 评论 0原文

我有一个形成曲线的样本向量。假设其中有 1000 个点。如果我想将其拉伸到填充 1500 个点,给出不错结果的最简单算法是什么?我正在寻找一些只有几行 C/C++ 的东西。

我总是想增加向量的大小,并且新向量可以是当前向量大小的 1.1 倍到 50 倍。

谢谢!

I've got a vector of samples that form a curve. Let's imagine there are 1000 points in it. If I want to stretch it to fill 1500 points, what is the simplest algorithm that gives decent results? I'm looking for something that is just a few lines of C/C++.

I'll always want to increase the size of the vector, and the new vector can be anywhere from 1.1x to 50x the size of the current vector.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

想念有你 2024-09-18 01:20:11

这是用于线性和二次插值的 C++。
interp1( 5.3, a, n ) 是 a[5] + .3 * (a[6] - a[5]), .3 从 a[5] 到 a[6 ];
interp1array( a, 1000, b, 1500 ) 会将 a 拉伸到 b
interp2( 5.3, a, n ) 通过 3 个最近的点 a[4] a[5] a[6] 绘制抛物线:比 interp1 更平滑,但仍然更快。
(样条线使用 4 个最近的点,更加平滑;如果你读过 python,请参阅
基本样条插值-在 numpy 的几行中

// linear, quadratic interpolation in arrays
// from interpol.py denis 2010-07-23 July

#include <stdio.h>
#include <stdlib.h>

// linear interpolate x in an array
// inline
float interp1( float x, float a[], int n )
{
    if( x <= 0 )  return a[0];
    if( x >= n - 1 )  return a[n-1];
    int j = int(x);
    return a[j] + (x - j) * ( a[j+1] - a[j] );
}

// linear interpolate array a[] -> array b[]
void interp1array( float a[], int n, float b[], int m )
{
    float step = float( n - 1 ) / (m - 1);
    for( int j = 0; j < m; j ++ )
    {
        b[j] = interp1( j*step, a, n );
    }
}

//..................................................................
// parabola through 3 points, -1 < x < 1
float parabola( float x, float f_1, float f0, float f1 )
{
    if( x <= -1 )  return f_1; 
    if( x >= 1 )  return f1; 
    float l = f0 - x * (f_1 - f0);
    float r = f0 + x * (f1 - f0);
    return (l + r + x * (r - l)) / 2;
}

// quadratic interpolate x in an array
float interp2( float x, float a[], int n )
{
    if( x <= .5  ||  x >= n - 1.5 )
        return interp1( x, a, n );
    int j = int( x + .5 );
    float t = 2 * (x - j);  // -1 .. 1
    return parabola( t, (a[j-1] + a[j]) / 2, a[j], (a[j] + a[j+1]) / 2 );
}

    // quadratic interpolate array a[] -> array b[]
void interp2array( float a[], int n, float b[], int m )
{
    float step = float( n - 1 ) / (m - 1);
    for( int j = 0; j < m; j ++ ){
        b[j] = interp2( j*step, a, n );
    }
}

int main( int argc, char* argv[] )
{
        // a.out [n m] --
    int n = 10, m = 100;
    int *ns[] = { &n, &m, 0 },
        **np = ns;
    char* arg;
    for( argv ++;  (arg = *argv) && *np;  argv ++, np ++ )
        **np = atoi( arg );
    printf( "n: %d  m: %d\n", n, m );

    float a[n], b[m];
    for( int j = 0; j < n; j ++ ){
        a[j] = j * j;
    }
    interp2array( a, n, b, m );  // a[] -> b[]

    for( int j = 0; j < m; j ++ ){
        printf( "%.1f ", b[j] );
    }
    printf( "\n" );
}

Here's C++ for linear and quadratic interpolation.
interp1( 5.3, a, n ) is a[5] + .3 * (a[6] - a[5]), .3 of the way from a[5] to a[6];
interp1array( a, 1000, b, 1500 ) would stretch a to b.
interp2( 5.3, a, n ) draws a parabola through the 3 nearest points a[4] a[5] a[6]: smoother than interp1 but still fast.
(Splines use 4 nearest points, smoother yet; if you read python, see
basic-spline-interpolation-in-a-few-lines-of-numpy.

// linear, quadratic interpolation in arrays
// from interpol.py denis 2010-07-23 July

#include <stdio.h>
#include <stdlib.h>

// linear interpolate x in an array
// inline
float interp1( float x, float a[], int n )
{
    if( x <= 0 )  return a[0];
    if( x >= n - 1 )  return a[n-1];
    int j = int(x);
    return a[j] + (x - j) * ( a[j+1] - a[j] );
}

// linear interpolate array a[] -> array b[]
void interp1array( float a[], int n, float b[], int m )
{
    float step = float( n - 1 ) / (m - 1);
    for( int j = 0; j < m; j ++ )
    {
        b[j] = interp1( j*step, a, n );
    }
}

//..................................................................
// parabola through 3 points, -1 < x < 1
float parabola( float x, float f_1, float f0, float f1 )
{
    if( x <= -1 )  return f_1; 
    if( x >= 1 )  return f1; 
    float l = f0 - x * (f_1 - f0);
    float r = f0 + x * (f1 - f0);
    return (l + r + x * (r - l)) / 2;
}

// quadratic interpolate x in an array
float interp2( float x, float a[], int n )
{
    if( x <= .5  ||  x >= n - 1.5 )
        return interp1( x, a, n );
    int j = int( x + .5 );
    float t = 2 * (x - j);  // -1 .. 1
    return parabola( t, (a[j-1] + a[j]) / 2, a[j], (a[j] + a[j+1]) / 2 );
}

    // quadratic interpolate array a[] -> array b[]
void interp2array( float a[], int n, float b[], int m )
{
    float step = float( n - 1 ) / (m - 1);
    for( int j = 0; j < m; j ++ ){
        b[j] = interp2( j*step, a, n );
    }
}

int main( int argc, char* argv[] )
{
        // a.out [n m] --
    int n = 10, m = 100;
    int *ns[] = { &n, &m, 0 },
        **np = ns;
    char* arg;
    for( argv ++;  (arg = *argv) && *np;  argv ++, np ++ )
        **np = atoi( arg );
    printf( "n: %d  m: %d\n", n, m );

    float a[n], b[m];
    for( int j = 0; j < n; j ++ ){
        a[j] = j * j;
    }
    interp2array( a, n, b, m );  // a[] -> b[]

    for( int j = 0; j < m; j ++ ){
        printf( "%.1f ", b[j] );
    }
    printf( "\n" );
}
初见你 2024-09-18 01:20:11

给出不错结果的最简单算法是什么?

Catmull-Rom 样条线。 (如果你想要平滑的曲线)

http://www.mvps.org/directx/articles /catmull/
http://en.wikipedia.org/wiki/Cubic_Hermite_spline

对于每个新项目计算分数位置在旧数组中,使用小数部分(f-floor(f))作为插值因子,使用“整数”(即floor(f))部分来查找最近的元素。

假设您正在操作可以数学插值的数据(浮点数)。如果无法插入数据(字符串),那么唯一的解决方案是使用旧数组中最近的可用元素。

如果数组中的点分布不均匀,则需要进行一些调整。

what is the simplest algorithm that gives decent results?

Catmull-Rom splines. (if you want a smooth curve)

http://www.mvps.org/directx/articles/catmull/
http://en.wikipedia.org/wiki/Cubic_Hermite_spline

For each new item calculate fractional position in old array, use use fractional part (f - floor(f)) as interpolation factor, and "integer" (i.e. floor(f)) part to find nearest elements.

That is assuming that you're operating on data that can be mathematically interpolated (floats). If data cannot be interpolated (strings), then the only solution is to use nearest available element of old array.

You'll need some tweaking if points in array aren't evenly distributed.

桃酥萝莉 2024-09-18 01:20:11

我能想到的最简单的选择只是一个基于平均值扩展数组的 fn ,因此:

x,y,z

变为

x, avg(x,y), y, avg (y,z), z

如果您需要更多数据点,只需在向量上运行多次即可。

Simplest option I can think of is just a fn that expands the array based on mean averages, so:

x,y,z

becomes

x, avg(x,y), y, avg (y,z), z

If you need more data points, just run it multiple times on the vector.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文