当前位置:首页 科普知识 贝塞尔曲线算法

贝塞尔曲线算法

发布时间:2023-09-07 01:07:06

贝赛尔曲线的拆分是指将贝赛尔曲线分解成逼近的多边形。可以用来判断贝赛尔曲线的选中,以及显示贝赛尔曲线的旋转效果等。

贝塞尔曲线算法详细介绍

贝赛尔曲线的拆分是指将贝赛尔曲线分解成逼近的多边形。可以用来判断贝赛尔曲线的选中,以及显示贝赛尔曲线的旋转效果等。

贝塞尔曲线算法

贝塞尔曲线算法贝赛尔曲线

贝塞尔曲线算法简单介绍:

贝赛尔曲线的每一个顶点都有两个控制点,用于控制在该顶点两侧的曲线的弧度。所以本函数的顶点数组的记录方式是:控制点+顶点+控制点+控制点+顶点+控制点+……。所以两个顶点之间的曲线是由两个顶点以及两个顶点之间的控制点来决定的。

==主函数PolyBezierToPolys==

贝塞尔曲线算法主要类型申明

typedef CArray<CPoint,CPoint> CPtArray;//点动态数组类型

贝塞尔曲线算法参数说明

bezierPts---贝赛尔曲线顶点和控制点数组

bClose------是否封闭的贝赛尔曲线

polyPt-----拆分后的多边形点数组

precision---拆分精度

bool PolyBezierToPolys(CPtArray &bezierPts,

bool bClose,CPtArray &polyPt,int precision)

{

polyPt.RemoveAll();

CPtArray apt;

int i,count = bezierPts.GetSize();

贝塞尔曲线算法详细内容

//从1开始,是因为第一个是控制点,如果曲线不封闭,那么第一个控制点是没有用的。

//每一段贝赛尔曲线由相邻的两个顶点和之间的两个控制点决定,所以频率为3(后一个顶点在下一组中还要使用)

for(i=1;i<count-2;i+=3){

BezierToPoly(&bezierPts,apt,precision); //拆分每一段

polyPt.Append(apt);//拆分完成,加入数组

}

//如果是封闭曲线,那么需要将最后一个顶点和第一个顶点以及最后一个控制点以及第一个控制点组成一组进行拆分

if(bClose){

CPoint ptBuffer;

ptBuffer = bezierPts;

ptBuffer = bezierPts;

ptBuffer = bezierPts;

ptBuffer = bezierPts;

BezierToPoly(&ptBuffer, apt,precision);

polyPt.Append(apt);

}

count = polyPt.GetSize();

i=0;

//过滤相邻的值相等的点(由于精度和误差,可能会有一些坐标值相同的相邻拆分点)

while(i<count-1){

if(polyPt ==polyPt){

polyPt.RemoveAt(i+1);

count--;

continue;

}

i++;

}

return true;

}

//拆分贝赛尔曲线

bool InciseBezier(CPoint *pSrcPt, CPoint *pDstPt)

{

CPoint buffer;

int i;

for(i=0;i<3;i++){

buffer = pSrcPt + pSrcPt;

buffer.x /=2;

buffer.y /=2;

}

for(i=0;i<2;i++){

buffer = buffer + buffer;

buffer.x /=2;

buffer.y /=2;

}

buffer = buffer + buffer;

buffer.x /=2;

buffer.y /=2;

pDstPt=pSrcPt;

pDstPt=buffer;

pDstPt=buffer;

pDstPt=buffer;

pDstPt=buffer;

pDstPt=buffer;

pDstPt=pSrcPt;

return true;

贝塞尔曲线算法

}

//拆分一组贝赛尔曲线段

bool BezierToPoly(CPoint *pSrcPts,CPtArray &polyPt,int precision)

{

polyPt.RemoveAll();

polyPt.SetSize(4);

polyPt = pSrcPts;

polyPt = pSrcPts;

polyPt = pSrcPts;

polyPt = pSrcPts;

CPoint ptBuffer;

int i,j,count =4;

bool bExit;

while(true){

bExit = true;

for(i=0;i<count-1;i+=3){

// if(GetBezierGap(&polyPt)>precision){

if(!EndBezierCut(&polyPt, precision)){

bExit = false;

InciseBezier(&polyPt, ptBuffer);

polyPt.RemoveAt(i+1,2);

polyPt.InsertAt(i+1,ptBuffer,5);

for(j=0;j<4;j++)

polyPt = ptBuffer;

i += 3;

count += 3;

}

}

if(bExit)

break;

}

count = polyPt.GetSize();

i=0;

while(i<count-1){

if(polyPt ==polyPt){

polyPt.RemoveAt(i+1);

count--;

continue;

}

i++;

}

return true;

}

/计算贝赛尔曲线两个顶点的纵向和横向的最大距离

int GetBezierGap(CPoint *p)

{

int gap = 0;

for(int i=1;i<4;i++){

if(abs(p.x-p.x)>gap)

gap=abs(p.x-p.x);

if(abs(p.y-p.y)>gap)

gap=abs(p.y-p.y);

}

return gap;

}

//判断是否可以终止更精细得拆分

bool EndBezierCut(CPoint *ptBezier, int nExtent)

{

double C,dx,dy,delt,delt1,delt2;

if (nExtent<2)

nExtent = 2;

dx = (double)(ptBezier.x - ptBezier.x);

dy = (double)(ptBezier.y - ptBezier.y);

C = dx * ptBezier.y - dy * ptBezier.x;

delt = (double)nExtent*nExtent*(dy*dy+dx*dx);

delt1 = dy * ptBezier.x - dx * ptBezier.y + C;

delt2 = dy * ptBezier.x - dx * ptBezier.y + C;

delt1 = delt1 * delt1;

delt2 = delt2 * delt2;

贝塞尔曲线算法

if (delt1 > delt || delt2 > delt)

return FALSE;

else

return TRUE;

温馨提示:
本文【贝塞尔曲线算法】由作者 爱百科 转载提供。 该文观点仅代表作者本人, 自学教育网 信息发布平台,仅提供信息存储空间服务, 若存在侵权问题,请及时联系管理员或作者进行删除。
(c)2008-2025 自学教育网 All Rights Reserved 汕头市灵创科技有限公司
粤ICP备2024240640号-6