我有一张包含1000和x坐标和y坐标的表格。找到匹配函数方程的最快方法是什么?
表格如下:
t - y
0 - 0.3113
1 - 0.5493
2 - 0.7190
3 - 0.6474
4 - 0.9200
5 - 0.2467
6 - 0.8068
7 - 0.5910
8 - 0.8302
9 - 0.2612
10 - 0.9869
t代表时间,y代表振幅。
我现在想要创建一个方程式,在某个时间t点击所有这些点y。从一个y到另一个的过渡应该是如此平滑(线性?),也没有直线。我希望它是一种像异步正弦波一样的波形。
有人知道如何做到这一点吗?
答案 0 :(得分:0)
您可以使用三次样条线在每对点之间创建立方体段。样条曲线将确保您点击所有点并且段之间的连续性高于0.连续性0表示使用线来连接点。下面是Catmull-Rom样条曲线的实现,它是最简单/最酷的样条曲线之一。
的买者强>
该实现假设x是单调递增的
import java.util.Arrays;
public class CatmullRomSpline
{
protected double[] _x;
protected double[] _y;
public CatmullRomSpline(final double[] x, final double[] y)
{
this._x = x;
this._y = y;
}
public double getValueAt(double x)
{
int length = this._x.length;
int index = Arrays.binarySearch(this._x, x);
double result;
// Exact match was found
if(index >= 0)
{
result = this._y[index];
}
// x is smaller than the smaller value in the sequence
else if(index == -1)
{
result = -1;
}
// x is larger than the largest number in the sequence
else if(index == -length - 1)
{
result = -2;
}
// the number is between two of the numbers in the sequence
else
{
index = -(index + 2);
double p0, p1, p2, p3;
if(index == 0)
{
p1 = this._y[0];
p2 = this._y[1];
p3 = this._y[2];
p0 = 2 * p1 - p2;
}
else if(index >= length - 2)
{
p0 = this._y[length - 3];
p1 = this._y[length - 2];
p2 = this._y[length - 1];
p3 = 2 * p2 - p1;
}
else
{
p1 = this._y[index];
p2 = this._y[index + 1];
p3 = this._y[index + 2];
p0 = this._y[index - 1];
}
// Normalize range from [0, 1] to agree with the derivation of the spline
x = (x - this._x[index]) / (this._x[index + 1] - this._x[index]);
double c0 = p1;
double c1 = p2 - p0;
double c2 = p2 - p1;
double c3 = p1 - p3;
double c4 = c1 - c3;
result = c0 + x * (0.5 * c1 + x * (0.5 * c3 + 3 * c2 - c1 + x * (0.5 * c4 - 2 * c2)));
}
return result;
}
public static void main(String[] args)
{
// I'm fitting a parabola from t = 1 to t = 4
double[] t = new double[] {0, 1, 2, 3, 4, 5};
double[] y = new double[] {0, 1, 4, 9, 16, 25};
int noPoints = 6;
double[] tHat = linspace(1.0, 4.0, noPoints);
CatmullRomSpline csp = new CatmullRomSpline(t, y);
for(double value : tHat)
{
System.out.printf("y(t = %.4f) = %.4f\n", value, csp.getValueAt(value));
}
/* Output
y(t = 1.0000) = 1.0000
y(t = 1.5000) = 2.2500
y(t = 2.0000) = 4.0000
y(t = 2.5000) = 6.2500
y(t = 3.0000) = 9.0000
y(t = 3.5000) = 12.2500
y(t = 4.0000) = 16.0000
*/
}
public static double[] linspace(double begin, double end, int noPoints)
{
double[] arr = new double[noPoints + 1];
double delta = (end - begin) / noPoints;
for(int i = 0; i < noPoints; i++)
{
arr[i] = begin + i * delta;
}
arr[noPoints] = end;
return arr;
}
}