导航:首页 > 源码编译 > bezier曲线绘制算法

bezier曲线绘制算法

发布时间:2022-07-14 12:19:17

㈠ 高次Bezier曲线的绘制问题

将程序中
long Factor(int nS) //求nS!
{long Temp=1;for(int i=1;i<=nS;i++)Temp*=i;return Temp;};
改成
double Factor(int nS) //求nS!
{double Temp=1;for(int i=1;i<=nS;i++)Temp*=i;return Temp;};
即可

㈡ 三次Bezier曲线绘制编程

顺便练一下贝塞尔函数,写了一个applet,每秒钟随机生成4个点展示效果。

满足题目要求的接口。

importjava.applet.Applet;

importjava.awt.Color;

importjava.awt.Graphics;

importjava.util.Random;

importjava.util.Timer;

importjava.util.TimerTask;

publicclassTestextendsApplet{

=-1570645570118871214L;

privateintpx[],py[];

privateRandomrnd;

@Override

publicvoidinit(){

rnd=newRandom(System.currentTimeMillis());

px=newint[4];

py=newint[4];

Timert=newTimer();

t.scheleAtFixedRate(newTimerTask(){

@Override

publicvoidrun(){

repaint();

}

},0,1000);

}

privatevoidgenerate(){

for(inti=0;i<4;i++){

px[i]=rnd.nextInt(150);

py[i]=rnd.nextInt(150);

}

}

staticpublicvoiddrawBezier(

Graphicsg,

intx0,inty0,

intx1,inty1,

intx2,inty2,

intx3,inty3){

int

px[]={x0,x1,x2,x3},

py[]={y0,y1,y2,y3};

g.setColor(Color.RED);

for(inti=0;i<px.length;i++){

g.fillOval(px[i],py[i],5,5);

}

g.setColor(Color.GREEN);

doublex=0,y=0;

intc=0;

for(doublet=0;t<=1;t+=0.01){

doubledx=cubicBezier(t,px),

dy=cubicBezier(t,py);

System.out.println("dx:"+dx+",dy:"+dy);

if(c++>0)g.drawLine((int)x,(int)y,(int)dx,(int)dy);

x=dx;y=dy;

}

}

(doublet,intp[]){

returnMath.pow(1-t,3)*p[0]+

3*t*Math.pow(1-t,2)*p[1]+

3*Math.pow(t,2)*(1-t)*p[2]+

Math.pow(t,3)*p[3];

}

@Override

publicvoidpaint(Graphicsg){

generate();

drawBezier(g,

px[0],py[0],

px[1],py[1],

px[2],py[2],

px[3],py[3]

);

}

}

㈢ 求二次贝塞尔曲线 算法实现

typedefstruct

{

floatx;

floaty;

}Point2D;

/*cp在此是四个元素的数组:

cp[0]为起点,或上图中的P0

cp[1]为第一控制点,或上图中的P1

cp[2]为第二控制点,或上图中的P2

cp[3]为结束点,或上图中的P3

t为参数值,0<=t<=1*/

Point2DPointOnCubicBezier(Point2D*cp,floatt)

{

floatax,bx,cx;floatay,by,cy;

floattSquared,tCubed;Point2Dresult;

/*计算多项式系数*/

cx=3.0*(cp[1].x-cp[0].x);

bx=3.0*(cp[2].x-cp[1].x)-cx;

ax=cp[3].x-cp[0].x-cx-bx;

cy=3.0*(cp[1].y-cp[0].y);

by=3.0*(cp[2].y-cp[1].y)-cy;

ay=cp[3].y-cp[0].y-cy-by;

/*计算t位置的点值*/

tSquared=t*t;

tCubed=tSquared*t;

result.x=(ax*tCubed)+(bx*tSquared)+(cx*t)+cp[0].x;

result.y=(ay*tCubed)+(by*tSquared)+(cy*t)+cp[0].y;

returnresult;

}

/*ComputeBezier以控制点cp所产生的曲线点,填入Point2D结构数组。

调用方必须分配足够的空间以供输出,<sizeof(Point2D)numberOfPoints>*/

voidComputeBezier(Point2D*cp,intnumberOfPoints,Point2D*curve)

{

floatdt;inti;

dt=1.0/(numberOfPoints-1);

for(i=0;i<numberOfPoints;i++)

curve[i]=PointOnCubicBezier(cp,i*dt);

}

㈣ Bezier曲线 算法 程序

看一下下面的Bezier曲线绘制程序,没有错误提示,但是绘制不出Bezier曲线#include "stdafx.h"#include "Test.h"#include "TestDoc.h"#include "TestView.h"#include "math.h"//包含数学头文件#define N_MAX_POINT 10//控制多边形的最大顶点数#define ROUND(a) int(a+0.5)//四舍五入#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CTestViewIMPLEMENT_DYNCREATE(CTestView, CView)BEGIN_MESSAGE_MAP(CTestView, CView) //{{AFX_MSG_MAP(CTestView) ON_COMMAND(ID_MENUBezierCurve, OnMENUBezierCurve) ON_WM_LBUTTONDOWN() ON_WM_RBUTTONDOWN() //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CTestView construction/destructionCTestView::CTestView(){ // TODO: add construction code here Flag=false;}CTestView::~CTestView(){}BOOL CTestView::PreCreateWindow(CREATESTRUCT& cs){ // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CView::PreCreateWindow(cs);}/////////////////////////////////////////////////////////////////////////////// CTestView drawingvoid CTestView::OnDraw(CDC* pDC){ CTestDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here}/////////////////////////////////////////////////////////////////////////////// CTestView printingBOOL CTestView::OnPreparePrinting(CPrintInfo* pInfo){ // default preparation return DoPreparePrinting(pInfo);}void CTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){ // TODO: add extra initialization before printing}void CTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){ // TODO: add cleanup after printing}/////////////////////////////////////////////////////////////////////////////// CTestView diagnostics#ifdef _DEBUGvoid CTestView::AssertValid() const{ CView::AssertValid();}void CTestView::Dump(CDumpContext& dc) const{ CView::Dump(dc);}CTestDoc* CTestView::GetDocument() // non-debug version is inline{ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTestDoc))); return (CTestDoc*)m_pDocument;}#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////// CTestView message handlersvoid CTestView::OnMENUBezierCurve()//菜单函数{ // TODO: Add your command handler code here RedrawWindow(); AfxGetMainWnd()->SetWindowText("曲线和曲面:Bezier曲线");//显示标题 MessageBox("单击左键绘制控制多边形,单击右键绘制曲线","提示",MB_OK); pt=new CPoint[N_MAX_POINT]; Flag=true;CtrlPoint=0;}void CTestView::DrawBezier()//绘制Bezier曲线{ CClientDC dc(this); double x,y; int rate=800,n; n=CtrlPoint-1; for(double t=0;t<=1;t+=1.0/rate) { x=0;y=0; for(int i=0;i<=n;i++) { x+=pt[i].x*Cnk(n,i)*pow(t,i)*pow(1-t,n-i); y+=pt[i].y*Cnk(n,i)*pow(t,i)*pow(1-t,n-i); } dc.SetPixel(ROUND(x),ROUND(y),RGB(0,0,255));//曲线颜色 }}double CTestView::Cnk(const int &n, const int &i)//计算Bernstein第一项函数{ return double(Factorial(n)/(Factorial(i)*Factorial(n-i)));}int CTestView::Factorial(int m)//阶乘函数{ int f=1; for(int i=1;i<=m;i++) f*=i; return f;}void CTestView::DrawCharPolygon()//绘制控制多边形函数{ CClientDC dc(this); CPen MyPen,*pOldPen; MyPen.CreatePen(PS_SOLID,3,RGB(0,0,0));//控制多边形 pOldPen=dc.SelectObject(&MyPen); for(int i=0;i<CtrlPoint;i++) { if(i==0) { dc.MoveTo(pt[i]); dc.Ellipse(pt[i].x-2,pt[i].y-2,pt[i].x+2,pt[i].y+2); } else { dc.LineTo(pt[i]); dc.Ellipse(pt[i].x-2,pt[i].y-2,pt[i].x+2,pt[i].y+2); } } dc.SelectObject(pOldPen); MyPen.DeleteObject();}void CTestView::OnLButtonDown(UINT nFlags, CPoint point)//获得屏幕控制点坐标函数{ // TODO: Add your message handler code here and/or call default CView::OnLButtonDown(nFlags, point); if(Flag) { pt[CtrlPoint].x=point.x; pt[CtrlPoint].y=point.y; if(CtrlPoint<N_MAX_POINT) CtrlPoint++; else Flag=false; DrawCharPolygon(); }}void CTestView::OnRButtonDown(UINT nFlags, CPoint point)//调用绘制Bezier曲线函数{ // TODO: Add your message handler code here and/or call default Flag=false; DrawBezier(); CView::OnRButtonDown(nFlags, point);}

㈤ 请问用MATLAB怎么绘制bezier曲线

function
[x,y]=bezier(x,y)
%用法:
%bezier(x,y)
%
生成n-1次贝塞尔曲线,其中x和y是n个点的坐标
%h=bezier(x,y)
%
生成n-1次贝塞尔曲线并返回曲线句柄
%[x,y]=bezier(x,y)
%
返回n-1次贝塞尔曲线的坐标
%例子:
%bezier([5,6,10,12],[0
5
-5
-2])
n=length(x);
t=linspace(0,1);
xx=0;yy=0;
for
k=0:n-1
tmp=nchoosek(n-1,k)*t.^k.*(1-t).^(n-1-k);
xx=xx+tmp*x(k+1);
yy=yy+tmp*y(k+1);
end
if
nargout==2
x=xx;y=yy;
end
h=plot(xx,yy);
if
nargout==1
x=h;
end

㈥ 贝塞尔曲线算法的详细内容

//从1开始,是因为第一个是控制点,如果曲线不封闭,那么第一个控制点是没有用的。
//每一段贝赛尔曲线由相邻的两个顶点和之间的两个控制点决定,所以频率为3(后一个顶点在下一组中还要使用)
for(i=1;i<count-2;i+=3){
BezierToPoly(&bezierPts,apt,precision); //拆分每一段
polyPt.Append(apt);//拆分完成,加入数组
}
//如果是封闭曲线,那么需要将最后一个顶点和第一个顶点以及最后一个控制点以及第一个控制点组成一组进行拆分
if(bClose){
CPoint ptBuffer[4];
ptBuffer[0] = bezierPts[count-2];
ptBuffer[1] = bezierPts[count-1];
ptBuffer[2] = bezierPts[0];
ptBuffer[3] = bezierPts[1];
BezierToPoly(&ptBuffer[0], apt,precision);
polyPt.Append(apt);
}
count = polyPt.GetSize();
i=0;
//过滤相邻的值相等的点(由于精度和误差,可能会有一些坐标值相同的相邻拆分点)
while(i<count-1){
if(polyPt ==polyPt[i+1]){
polyPt.RemoveAt(i+1);
count--;
continue;
}
i++;
}
return true;
}
//拆分贝赛尔曲线
bool InciseBezier(CPoint *pSrcPt, CPoint *pDstPt)
{
CPoint buffer[3][3];
int i;
for(i=0;i<3;i++){
buffer[0] = pSrcPt + pSrcPt[i+1];
buffer[0].x /=2;
buffer[0].y /=2;
}
for(i=0;i<2;i++){
buffer[1] = buffer[0] + buffer[0][i+1];
buffer[1].x /=2;
buffer[1].y /=2;
}
buffer[2][0] = buffer[1][0] + buffer[1][1];
buffer[2][0].x /=2;
buffer[2][0].y /=2;
pDstPt[0]=pSrcPt[0];
pDstPt[1]=buffer[0][0];
pDstPt[2]=buffer[1][0];
pDstPt[3]=buffer[2][0];
pDstPt[4]=buffer[1][1];
pDstPt[5]=buffer[0][2];
pDstPt[6]=pSrcPt[3];
return true;
}
//拆分一组贝赛尔曲线段
bool BezierToPoly(CPoint *pSrcPts,CPtArray &polyPt,int precision)
{
polyPt.RemoveAll();
polyPt.SetSize(4);
polyPt[0] = pSrcPts[0];
polyPt[1] = pSrcPts[1];
polyPt[2] = pSrcPts[2];
polyPt[3] = pSrcPts[3];
CPoint ptBuffer[7];
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[1],5);
for(j=0;j<4;j++)
polyPt[i+2+j] = ptBuffer[2+j];
i += 3;
count += 3;
}
}
if(bExit)
break;
}
count = polyPt.GetSize();
i=0;
while(i<count-1){
if(polyPt ==polyPt[i+1]){
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[i-1].x)>gap)
gap=abs(p.x-p[i-1].x);
if(abs(p.y-p[i-1].y)>gap)
gap=abs(p.y-p[i-1].y);
}
return gap;
}
//判断是否可以终止更精细得拆分
bool EndBezierCut(CPoint *ptBezier, int nExtent)
{
double C,dx,dy,delt,delt1,delt2;
if (nExtent<2)
nExtent = 2;
dx = (double)(ptBezier[3].x - ptBezier[0].x);
dy = (double)(ptBezier[3].y - ptBezier[0].y);
C = dx * ptBezier[0].y - dy * ptBezier[0].x;
delt = (double)nExtent*nExtent*(dy*dy+dx*dx);
delt1 = dy * ptBezier[1].x - dx * ptBezier[1].y + C;
delt2 = dy * ptBezier[2].x - dx * ptBezier[2].y + C;
delt1 = delt1 * delt1;
delt2 = delt2 * delt2;
if (delt1 > delt || delt2 > delt)
return FALSE;
else
return TRUE;
}

㈦ 对于2N+2个离散点,如何来构造Bezier曲线

如何利用VC + + 编程技术在图形系统中动态绘制任意阶Bezier 工程曲线方 法,并且使绘制的曲线具有捕捉、修改、动态增加型值点等功能。利用同样的方法,可以实现 B 样条、三次参数等其它工程曲线的绘制,从而扩大了Bezier 等曲线的工程应用。 关键词:Bezier 曲线; 动态绘制; 高阶; VC + + 中图分类号: TP391 文献标识码:A 文章编号:1671 - 5322(2004) 04 - 0029 - 05 UG、CATIA 等图形系统可以实现B 样条曲线 的动态绘制方法,但没有Bezier 、三次参数样条等 曲线的绘制方法。虽然B 样条曲线使用最广泛, 但Bezier 、三次参数样条在工程上也有较多的运 用。为拓宽工程曲线的应用范围, 在结合现行 Bezier 等曲线的算法的基础上,利用VC + + 开发 工具实现了高阶Bezier 等曲线的绘制方法,较方 便地动态实现了曲线的修改。本设计模块可以单 独使用,也可作为一个模块嵌入其它图形系统中 使用。从绘制Bezier 曲线的方法中可了解用现行 绘图软件实现曲线的动态绘制、曲线的识别、拖动 型值点修改曲线等编程方法,该方法对于开发其 它专业图形系统有极大的帮助。

㈧ 如何实现任意阶次bezier曲线的生成

如何利用VC + + 编程技术在图形系统中动态绘制任意阶Bezier 工程曲线方 法,并且使绘制的曲线具有捕捉、修改、动态增加型值点等功能。利用同样的方法,可以实现 B 样条、三次参数等其它工程曲线的绘制,从而扩大了Bezier 等曲线的工程应用。 关键词:Bezier 曲线; 动态绘制; 高阶; VC + + 中图分类号: TP391 文献标识码:A 文章编号:1671 - 5322(2004) 04 - 0029 - 05 UG、CATIA 等图形系统可以实现B 样条曲线 的动态绘制方法,但没有Bezier 、三次参数样条等 曲线的绘制方法。虽然B 样条曲线使用最广泛, 但Bezier 、三次参数样条在工程上也有较多的运 用。为拓宽工程曲线的应用范围, 在结合现行 Bezier 等曲线的算法的基础上,利用VC + + 开发 工具实现了高阶Bezier 等曲线的绘制方法,较方 便地动态实现了曲线的修改。本设计模块可以单 独使用,也可作为一个模块嵌入其它图形系统中 使用。从绘制Bezier 曲线的方法中可了解用现行 绘图软件实现曲线的动态绘制、曲线的识别、拖动 型值点修改曲线等编程方法,该方法对于开发其 它专业图形系统有极大的帮助。 1 Bezier 曲线的算法 1. 1 Bezier 曲线的描述 设 P 0 , P 1 , P 2 , …, P n , 为 n 阶Bezier 曲线的特 征多边形控制点,则Bezier 曲线一般表达式为 P( t) = ∑ n i =0 B i , n ( t) P i , 0 ≤t ≤1 (1) 其中: B i , n ( t) = C n i (1 - t) n - i t i ( i = 0 , 1 , …n) 1. 2 绘制Bezier 曲线的条件 绘制Bezier 曲线的条件有两种,一是给出型 值点坐标,另一是给出控制点坐标。在计算中,一 般最终是利用控制点坐标计算来绘制曲线的。当 给出的数据是型值点时,要利用型值点的坐标值 反求出控制点坐标,再利用控制点坐标进行插补 运算求出曲线的坐标,反求控制点的算法为: 设给出的型值点为 Q 0 , Q 1 , Q 2 …Q n , 要反求 的控制点为 P 0 , P 1 , P 2 …P n , 设参数 t = 0 , 1/ n , 2/ n …1 时分别经过 Q 0 , Q 1 , Q 2 …Q n , 根据Bezier 定义有 Q 0 = P(0) = P 0 Q 1 = P(1/ n) = B 0 , n (1/ n) P 0 + B 1 , n (1/ n) P 1 + … + B n , n (1/ n) P n …… (2) Q n- 1 = P( ( n - 1) / n) = B 0 , n ( ( n - 1) / n) P 0 + B 1 , n ( ( n - 1) / n) P 1 + …+ B n , n P n Q n = P n 把上式写成矩阵形式,利用矩阵的求逆运算, 求出控制点为式(3) 。

2 绘制曲线类的方法 2. 1 构造Bezier 曲线类 在VC + + 中绘制Bezier 曲线,首先建立Bezi2 er 曲线类,利用Bezier 类的指针来对Bezier 曲线进 行控制。在VC + + 中所构造Bezier 的曲线类为 CBezier : : CBezier ( short ColorPen , short Color2 Brush , float LineWide , short LineType , float x- Scale , short Layer , int id-only , bool Delete , BpointStruct 3 BpointList) : CDraw ( ColorPen , ColorBrush ,LineWide , LineType ,x- Scale ,Layer ,id-only ,Delete) 各参数的控制对象分别为线型、颜色、线宽、 比例、图层、曲线 ID 号、删除状态、型值点数目、存 放型值点的结构指针,其中BpointStruct 结构有 x 和y 两个成员, 存放型值点坐标, CDraw 类为 CBezie 的基类,该类的各个参数在构造成时完成 初始化。CBezier 类成员有: int m-Numble ;/ / 存放结点的数目 BPointStruct 3 m-BpointList ;/ / 存放型值点的坐 标 BPointStruct 3 m- CpointList ;/ / 存放反求的控制 点的坐标 void Draw ( CDC 3 pDC , int m-DrawMode , int m- DrawMode1 ,short BackColor) ;/ / 绘制曲线函数 BOOL IsPoint (float x ,float y ,float jl ,float blc ,int 3 No) ; / / 判断曲线是否选中函数 virtual void MDpoint ( int num , float x , float y) ;/ / 修改控制点函数 void GetRect (float 3 minX,float 3 minY,float 3 maxX, float 3 maxY) ;获得曲线区域函数 virtual~CBezier () ;/ / CBezier 的析函数 CBezier 类成员在类构造时完成参数数值的 传递,绘制曲线时构造一个CBezier 类对象。为了 存储构造的对象指针,在文档类中建立一个存放 曲线指针的指针m-BezierArray。 CTypedPtrArray < CObArray , CBezier 3 > m- BezierArray。 2. 2 动态绘制Bezier 曲线 Bezier 曲线类由Draw 函数完成曲线的绘制, 在Draw中完成曲线的反求控制点、插补运算、区 域的计算, 设置线型、颜色、线宽等功能。Bezier 曲线的绘制方法是当用户选择绘制 Bezier 曲线的 功能时,用户在屏幕上拾取型值点时或输入型值 点坐标,在屏幕上动态绘制曲线,绘制中每增加一 个型值点时,则Bezier 曲线的阶次增加一阶,此方 法可以实现任意阶的Bezier 曲线的绘制, 这和B 样条的曲线绘制方法不同,B 样条曲线可用多个 三次B 样条曲线绘制N 个型值点样条曲线,得到 的曲线是光滑连续的,而Bezier 曲线随着型值点 个数的增加,若用升阶的方法计算,则绘制程序要 根据型值点的个数重新计算曲线的坐标。Draw 函数绘制的程序流程如图1 所示。 图1 Draw函数的流程图 Fig. 1 Process flowfor drawfunction 在程序中构造成计算矩阵时,把与坐标值对 应的参数 t 的值代入伯恩斯坦基函数计算出与各 型值点对应的各个基函数值,其中调用了求阶乘、 求幂等函数,然后组合成一个基函数矩阵,再调用 矩阵的求逆运算,本模块中采用全选主元高斯消 �9�9 0 3 �9�9 盐城工学院学报(自然科学版) 第17 卷 去法进行求逆,得到计算的系数矩阵,求出控制点 坐标,根据Bezier 曲线的计算公式计算出曲线的 坐标。绘制Bezier 曲线调用了CDC类的绘制直线 方法,用直线段来近似代替曲线,图形系统中绘制 曲线大多采用这种方法,曲线的近似程度和所采 用的插值间距有关。为了得到好的显示效果,要 把间距控制视觉能接受的范围内。由于无论曲线 多长, t 的值都是在0~1 之间, 当 t 的分隔间距恒 定时, 在动态绘制过中, 随着曲线长度的增加, 直 线的逼近效果越差。t 的划分方法很多, 可以利 用等间距、等弦长方法来解决这一问题, 一般来 说, t 的插值间距为非均匀, 而让每一段代替曲线 的直线段的距离为定值, 获得好的视觉效果。 2. 3 增加Bezier 曲线 在动态绘制过程中,当鼠标移动过程中,曲线 也随着鼠标的位置不同实现重画。这时的图形指 针并没有存储到Bezier 曲线类的m-BezierArray 数 组中。只有当完成曲线绘制时,发出命令后才进 行曲线的最后绘制,对象指针才加入到 m-Bezier2 Array 中存储。当用鼠标的右键结束绘制时,在鼠 标的消息函数中增加以下语句 pDoc > AddCBezier ( m-pColor , m- brColor , m- LineWide ,m-LineType ,m-xScale ,m-Layer ,id-only ,0 , PushNumb ,BPointXyz) - > Draw( &ddd ,0 ,1 ,m- bCol2 or) ; AddCBezier 函数在文档类中定义, 它完成对 象的增加,存储指针。得到指针后,调用Draw 函 数绘制直线。 3 实现曲线类动态修改 3. 1 曲线的捕捉 曲线的捕捉功能是图形系统的基本功能,要 实现曲线的捕捉前提是获得曲线类的对象指针, 建立Bezier 曲线类的目的就是为了实现曲线的捕 捉、移动、修改、删除、恢复, 移动和缩放功能。 Bezier 类中 IsPoint 函数就是为了实现鼠标移动过 程中鼠标位置与曲线之间距离的计算,距离判别 最简单的方法是计算鼠标点位置和对象中的存储 的型值点距离,若距离在设定的范围内,则把选中 的图形突出显示。IsPoint 函数不但返回曲线是否 选中的逻辑值,而且利用参数返回选中曲线的型 值点的序号。更为复杂的方法是把鼠标点和曲线 的坐标进行判别,这种判别方法可用的判别点多, 曲线易选中,但计算复杂,系统采用第一种方法实 现捕捉功能。 3. 2 曲线的修改 在绘图过程中,有时需要修改图形,一般是通 过修改型值或控制点的位置来达到所要求的曲线 形状。为了修改型值或控制点,在Bezier 类中增 加了Mdpoint 函数, 在函数中根据 IsPoint 返回的 型值点或控制点的序号替换它们的坐标,然后重 画曲线,这样就实现了动态修改的功能。 3. 3 曲线的删除、恢复 曲线删除有两种情况,一种是可以恢复的,另 一种是不可恢复的。不可恢复的的删除,只要在 存放对象指针的m-BezierArray 数组中删除所要删 除的曲线指针。如果是可恢复的删除,只是在对 象的成员中增加了删除标志,在重画曲线时,做了 删除标志的曲线不绘制,而对象指针并没有从指 针数组中删除。 3. 4 曲线的移动和缩放 曲线移动是让曲线做平移。平移时,根据平 移的 X, Y方向的距离在曲线的型值或控制点上 加上一个平移值,该值的正负号表示移动方向。 曲线的缩放是根据图形的缩放比例对图形放 大或缩小。在程序中,增加了缩放的比例因子和 从逻辑坐标到实际坐标转换函数VPtoDP 以及从 实际坐标到逻辑坐标的转换函数DPtoVP ,在坐标 转换函数中,通过缩放的比例因子改变坐标值达 到缩放目的。VPtoDP 函数定义如下 void CVDrawView: : DPtoVP (float x ,float y , int 3 X,int 3 Y) { 3 X= (int) ( (x - m-xStart) / blc) ; if (m-MapMode = = 1) 3 Y= m- hScreen - (int) ( (y - m-yStart) / blc) ; else 3 Y= (int) ( (y - m-yStart) / blc) - m- hScreen ; } 其中,blc 就是坐标变换中的缩放因子,m-xS2 tart 、m-yStart 是调节整个图形的平行移动坐标。 4 实现曲线动态绘制的过程 在实现Bezier 曲线的绘制过程中,绘制过程 会调用了许多函数,利用了鼠标的消息函数来实 现绘图操作。具体实现的过程是先用鼠标单击左 键在屏幕上拾取曲线的型值点,当拖动鼠标时,曲 线随着鼠标的移动在不断的变化。

阅读全文

与bezier曲线绘制算法相关的资料

热点内容
喷油螺杆制冷压缩机 浏览:577
python员工信息登记表 浏览:375
高中美术pdf 浏览:159
java实现排列 浏览:511
javavector的用法 浏览:980
osi实现加密的三层 浏览:230
大众宝来原厂中控如何安装app 浏览:912
linux内核根文件系统 浏览:241
3d的命令面板不见了 浏览:524
武汉理工大学服务器ip地址 浏览:147
亚马逊云服务器登录 浏览:523
安卓手机如何进行文件处理 浏览:70
mysql执行系统命令 浏览:929
php支持curlhttps 浏览:142
新预算法责任 浏览:443
服务器如何处理5万人同时在线 浏览:249
哈夫曼编码数据压缩 浏览:424
锁定服务器是什么意思 浏览:383
场景检测算法 浏览:616
解压手机软件触屏 浏览:348