bezier拟合程序时出现的stack overflow

ex_impression 2008-11-14 10:17:37
用bezier曲线动态拟合一条手绘(mousemove记录的点)折线的程序,但是会出现stack overflow的错误,因为这个程序递归调用的很多次。如果鼠标记录的点在100左右的时候可以运行,但是点一多,比如300,就会提示stack overflow的提示,有时后会提示 内存泄漏。各位能不能看一到底是哪里出了问题,或者该怎么改写程序呢。

//pointsline指针记录了通过移动鼠标记录的手绘折线上的点,array_begin是每段拟合的初始点,array_end是每段拟合的结束点,PNum是拟合不成功时
//会--,然后从array_end前一个点来再次进行拟合,一直到一段BEZIER可以拟合后,把pNum传递给array_begin,然后再次递归,大概思路就是这样的
//mbezier指针是自己新建的一个bezier类,从线类继承而来,拟合好的数据点就记录在mbezier里面
void CPoly::BezierFitting(Point *&PointsLine,int array_Begin,int pNum, int array_End,CBezier* &mbezier) //
{
BOOL FittingOk=false;
if(pNum-array_Begin<=1) return;

Point P0,P1,P2,P3;

float A,B,C,D,Ex,Ey,Fx,Fy; //最小二乘法差数
A=0;B=0;C=0;D=0;Ex=0;Ey=0;Fx=0;Fy=0;

float *tt; //参数数组t=i/n
tt=new float[pNum-array_Begin+1];

for(int i=0;i<=pNum-array_Begin;i++)
{
float tem;
tt[i]=i/(float(pNum-array_Begin));
}

Point Q, Q0, Qn;
Q0 = PointsLine[array_Begin];
Qn = PointsLine[pNum];

if(array_Begin==0) //当从起点开始计算时
{
float tem_A,tem_BC,tem_D,tem_E,temX,temY;

for(int i=0;i<=pNum;i++)
{
tem_A = 3*tt[i]*(1-tt[i])*(1-tt[i]) * 3*tt[i]*(1-tt[i])*(1-tt[i]);
A = A+tem_A;

tem_BC = 3*tt[i]*(1-tt[i])*(1-tt[i]) * 3*tt[i]*tt[i]*(1-tt[i]);
B = B+tem_BC;

tem_BC = 3*tt[i]*(1-tt[i])*(1-tt[i]) * 3*tt[i]*tt[i]*(1-tt[i]);
C = C+tem_BC;

tem_D = 3*tt[i]*tt[i]*(1-tt[i]) * 3*tt[i]*tt[i]*(1-tt[i]);
D = D+tem_D;

Q = PointsLine[i];
temX = 3*tt[i]*(1-tt[i])*(1-tt[i])*Q.X-Q0.X*pow((1-tt[i]),3)*3*tt[i]*(1-tt[i])*(1-tt[i])-Qn.X*3*tt[i]*(1-tt[i])*(1-tt[i])*pow(tt[i],3);
temY = 3*tt[i]*(1-tt[i])*(1-tt[i])*Q.Y-Q0.Y*pow((1-tt[i]),3)*3*tt[i]*(1-tt[i])*(1-tt[i])-Qn.Y*3*tt[i]*(1-tt[i])*(1-tt[i])*pow(tt[i],3);
Ex = Ex + temX;
Ey = Ey + temY;

temX = 3*tt[i]*tt[i]*(1-tt[i])*Q.X-Q0.X*3*tt[i]*tt[i]*(1-tt[i])*pow((1-tt[i]),3)-Qn.X*3*tt[i]*tt[i]*(1-tt[i])*pow(tt[i],3);
temY = 3*tt[i]*tt[i]*(1-tt[i])*Q.Y-Q0.Y*3*tt[i]*tt[i]*(1-tt[i])*pow((1-tt[i]),3)-Qn.Y*3*tt[i]*tt[i]*(1-tt[i])*pow(tt[i],3);
Fx = Fx + temX;
Fy = Fy + temY;
}

P0 = PointsLine[0];
P1.X=(Ex*D-Fx*B)/(A*D-C*B);
P1.Y=(Ey*D-Fy*B)/(A*D-C*B);
P2.X =(Ex-A*P1.X)/B;
P2.Y =(Ey-A*P1.Y)/B;
P3 = PointsLine[pNum];
}
else
{
Point vector;
vector = mbezier->m_pPoints[mbezier->m_nHandles*3-2]-(mbezier->m_pPoints[mbezier->m_nHandles*3-3]); //方向矢量

float tem_a,tem_b,tem_c,tem_d,tem_e,tem_f,tem_g,tem_h,tem_k,S;
tem_a=0,tem_b=0,tem_c=0,tem_d=0,tem_e=0,tem_f=0,tem_g=0,tem_h=0,tem_k=0;

for(int i=0;i<=pNum-array_Begin;i++)
{
Q = PointsLine[i+array_Begin];

tem_a = tem_a+(vector.X*vector.X+vector.Y*vector.Y)*3*tt[i]*(1-tt[i])*(1-tt[i])*3*tt[i]*(1-tt[i])*(1-tt[i]);
tem_b = tem_b+vector.X*3*tt[i]*(1-tt[i])*(1-tt[i])*3*tt[i]*tt[i]*(1-tt[i]);
tem_c = tem_c+vector.Y*3*tt[i]*(1-tt[i])*(1-tt[i])*3*tt[i]*tt[i]*(1-tt[i]);
tem_d = tem_d+vector.X*Q.X*3*tt[i]*(1-tt[i])*(1-tt[i])+vector.Y*Q.Y*3*tt[i]*(1-tt[i])*(1-tt[i])-(vector.X*Q0.X+vector.Y*Q0.Y)*(pow((1-tt[i]),3)
*3*tt[i]*(1-tt[i])*(1-tt[i])+3*tt[i]*(1-tt[i])*(1-tt[i])*3*tt[i]*(1-tt[i])*(1-tt[i]))-(vector.X*Qn.X+vector.Y*Qn.Y)*(3*tt[i]*(1-tt[i])*(1-tt[i])*pow(tt[i],3));
tem_e = tem_e+vector.X*3*tt[i]*(1-tt[i])*(1-tt[i])*3*tt[i]*tt[i]*(1-tt[i]);
tem_f = tem_f+3*tt[i]*tt[i]*(1-tt[i])*3*tt[i]*tt[i]*(1-tt[i]);
tem_g = tem_g+Q.X*3*tt[i]*tt[i]*(1-tt[i])-Q0.X*(pow((1-tt[i]),3)*3*tt[i]*tt[i]*(1-tt[i])+3*tt[i]*tt[i]*(1-tt[i])*3*tt[i]*(1-tt[i])*(1-tt[i]))
-Qn.X*pow(tt[i],3)*3*tt[i]*tt[i]*(1-tt[i]);
tem_h = tem_h+vector.Y*3*tt[i]*(1-tt[i])*(1-tt[i])*3*tt[i]*tt[i]*(1-tt[i]);
tem_k = tem_k+Q.Y*3*tt[i]*tt[i]*(1-tt[i])-Q0.Y*(pow((1-tt[i]),3)*3*tt[i]*tt[i]*(1-tt[i])+3*tt[i]*tt[i]*(1-tt[i])*3*tt[i]*(1-tt[i])*(1-tt[i]))
-Qn.Y*pow(tt[i],3)*3*tt[i]*tt[i]*(1-tt[i]);
}

P0 = PointsLine[array_Begin];
P2.X = ((tem_d*tem_e-tem_g*tem_a)*tem_f+(tem_g*tem_h-tem_e*tem_k)*tem_c)/(tem_f*tem_b*tem_e-tem_f*tem_f*tem_a+tem_c*tem_f*tem_h);
S = (tem_g-tem_f*P2.X)/tem_e;
P2.Y = (tem_k-tem_h*S)/tem_f;
P1.X=P0.X+vector.X*S;
P1.Y=P0.Y+vector.Y*S;
P3 = PointsLine[pNum];
}

delete []tt; //删除参数数组

for(int i=array_Begin+1;i<pNum;i++) // 循环判断拟合误差(从begin 到end)
{
FittingOk=false;
Point point_tem1;
point_tem1=PointsLine[i];
BOOL a;
a=IsToleranceOk(point_tem1,30,P0,P1,P2,P3); //判断这一点到这一段bezier曲线的误差是否小于30
if(a==false)
{
break;
}
else FittingOk=true;
}


if(FittingOk==false) // 拟合不成功, --,继续递归
{
pNum--;

if((pNum-array_Begin)<=1)
{
return;
}
BezierFitting( PointsLine,array_Begin,pNum,array_End,mbezier);
}
else //拟合成功, 把控制点存入控制点数组, 递归
{
if(pNum-array_Begin==1)
{
return;
}

mbezier->m_nHandles++;
mbezier->m_nAllocs=mbezier->m_nHandles*3;
mbezier->m_pPoints = (Point*)realloc(mbezier->m_pPoints,mbezier->m_nAllocs*sizeof(Point)); //增加分配内存

if(array_Begin==0)
{
mbezier->m_pPoints[1]=P0;
mbezier->m_pPoints[2]=P1;
mbezier->m_pPoints[0]=P0+P0-P1;
mbezier->m_pPoints[3]=P2;
mbezier->m_pPoints[4]=P3;
}
else
{
mbezier->m_pPoints[mbezier->m_nHandles*3-4]=P1;
mbezier->m_pPoints[mbezier->m_nHandles*3-3]=P2;
mbezier->m_pPoints[mbezier->m_nHandles*3-2]=P3;

}
array_Begin=pNum;
pNum=array_End;

BezierFitting(PointsLine,array_Begin,pNum,array_End,mbezier);
}

}
...全文
41 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
ex_impression 2008-12-10
  • 打赏
  • 举报
回复
已解决 ,给分
nealwike 2008-11-14
  • 打赏
  • 举报
回复
~ ~,太长了.

7,540

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 VC.NET
社区管理员
  • VC.NET社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧