【发布时间】:2013-02-07 03:19:31
【问题描述】:
如果我有一个简单的二维矩阵,x 轴上的归一化值在 0 和 1 之间,y 轴在 0 和 1 之间,并且我在这个矩阵中有 3 个点,例如P1 (x=0.2,y=0.9)、P2 (x=0.5,y=0.1) 和 P3 (x=0.9,y=0.4)。
我怎样才能通过这些点简单地计算一条曲线,这意味着有一个函数可以为我提供任何 x 的 y。
我现在知道通过 3 个点有任意数量的可能曲线。但是,嘿,你知道我的意思:我想要一条平滑的曲线穿过它,可用于音频采样插值,可用于计算音量衰减曲线,可用于计算游戏中的怪物行走路径。
现在我在网上搜索了这个问题大约 3 天,我不敢相信这个任务没有可用的解决方案。所有关于 Catmull-rom-Splines、bezier-curves 和所有理论内容的文本都至少有一个点对我来说不可用。例如,Catmull-Rom-splines 需要在控制点之间有一个固定的距离(我会使用此代码并将 4.point-y 设置为 3.point y):
void CatmullRomSpline(float *x,float *y,float x1,float y1,float x2,float y2,float x3,float y3,float x4,float y4,float u)
{
//x,y are calculated for x1,y1,x2,y2,x3,y3 and x4,y4 if u is the normalized distance (0-1) in relation to the distance between x2 and x3 for my whiched point
float u3,u2,f1,f2,f3,f4;
u3=u*u*u;
u2=u*u;
f1=-0.5f * u3 + u2 -0.5f *u;
f2= 1.5f * u3 -2.5f * u2+1.0f;
f3=-1.5f * u3 +2.0f * u2+0.5f*u;
f4=0.5f*u3-0.5f*u2;
*x=x1*f1+x2*f2+x3*f3+x4*f4;
*y=y1*f1+y2*f2+y3*f3+y4*f4;
}
但是我没有看到x1到x4对y的计算有任何影响,所以我认为x1到x4必须有相同的距离?
...
或者贝塞尔代码不计算通过点的曲线。这些点(至少是 2. 点)似乎只对线上产生了力效应。
typedef struct Point2D
{
double x;
double y;
} Point2D;
class bezier
{
std::vector<Point2D> points;
bezier();
void PushPoint2D( Point2D point );
Point2D GetPoint( double time );
~bezier();
};
void bezier::PushPoint2D(Point2D point)
{
points.push_back(point);
}
Point2D bezier::GetPoint( double x )
{
int i;
Point2D p;
p.x=0;
p.y=0;
if( points.size() == 1 ) return points[0];
if( points.size() == 0 ) return p;
bezier b;
for (i=0;i<(int)points.size()-1;i++)
{
p.x = ( points[i+1].x - points[i].x ) * x + points[i].x;
p.y = ( points[i+1].y - points[i].y ) * x + points[i].y;
if (points.size()<=2) return p;
b.PushPoint2D(p);
}
return b.GetPoint(x);
}
double GetLogicalYAtX(double x)
{
bezier bz;
Point2D p;
p.x=0.2;
p.y=0.9;
bz.PushPoint2D(p);
p.x=0.5;
p.y=0.1;
bz.PushPoint2D(p);
p.x=0.9;
p.y=0.4;
bz.PushPoint2D(p);
p=bz.GetPoint(x);
return p.y;
}
这总比没有好,但它是 1. 非常慢(递归)和 2. 正如我所说并没有真正计算通过 2. 点的线。
外面有数学大脑可以帮助我吗?
【问题讨论】: