Bezier曲线原理及实现代码(c++)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Bezier曲线原理及实现代码(c++)
Bezier曲线原理及实现代码(c++)
2009-06-30 18:50:09| 分类: |字号
⼀、原理:
贝塞尔曲线于,由⼯程师(Pierre Bézier)所⼴泛发表,他运⽤贝塞尔曲线来为的主体进⾏设计。

贝塞尔曲线最初由于运⽤开发,以的⽅法求出贝塞尔曲线。

线性贝塞尔曲线
给定点 P0、P1,线性贝塞尔曲线只是⼀条两点之间的。

这条线由下式给出:
且其等同于。

⼆次⽅贝塞尔曲线的路径由给定点 P0、P1、P2的函数 B(t) 追踪:。

字型就运⽤了以组成的⼆次贝塞尔曲线。

P0、P1、P2、P3四个点在平⾯或在三维空间中定义了三次⽅贝塞尔曲线。

曲线起始于 P0⾛向 P1,并从 P2的⽅向来到 P3。

⼀般不会经过 P1或 P2;这两个点只是在那⾥提供⽅向资讯。

P0和 P1之间的间距,决定了曲线在转⽽趋进 P3之前,⾛向 P2⽅向的“长度有多长”。

形式为:。

现代的成象系统,如、和,运⽤了以组成的三次贝塞尔曲线,⽤来描绘曲线轮廓。

P0、P1、…、P n,其贝塞尔曲线即。

例如:。

如上公式可如下递归表达:⽤表⽰由点 P0、P1、…、P n所决定的贝塞尔曲线。


⽤平常话来说,阶贝塞尔曲线之间的插值。

⼀些关于参数曲线的术语,有
即多项式
,定义 00 = 1。

点 P i称作贝塞尔曲线的控制点。

以带有的贝塞尔点连接⽽成,起始于 P0并以 P n终⽌,称作贝塞尔多边形(或控制多边形)。

贝塞尔多边形的(convex hull)包含有贝塞尔曲线。

线性贝塞尔曲线函数中的t会经过由 P0⾄P1的 B(t) 所描述的曲线。

例如当t=0.25时,B(t) 即⼀条由点 P0⾄ P1路径的四分之⼀处。

就像由0 ⾄ 1 的连续t,B(t) 描述⼀条由 P0⾄ P1的直线。

为建构⼆次贝塞尔曲线,可以中介点 Q0和 Q1作为由 0 ⾄ 1 的t:
由 P0⾄ P1的连续点 Q0,描述⼀条线性贝塞尔曲线。

由 P1⾄ P2的连续点 Q1,描述⼀条线性贝塞尔曲线。

由 Q0⾄ Q1的连续点 B(t),描述⼀条⼆次贝塞尔曲线。

为建构⾼阶曲线,便需要相应更多的中介点。

对于三次曲线,可由线性贝塞尔曲线描述的中介点 Q0、Q1、Q2,和由⼆次曲线描述的点 R0、R1所建构:
对于四次曲线,可由线性贝塞尔曲线描述的中介点 Q0、Q1、Q2、Q3,由⼆次贝塞尔曲线描述的点 R0、R1、R2,和由三次贝塞尔曲线描述的点 S0、S1所建构:
P(t)=(1-t)3P0+3t(1-t)2P1+3t2(1-t)P2+t3P3
矩阵表⽰为:
,。

⼆、算法(c++)
⼯程⽬录是:Win32App
vc6.0
#include<windows.h>
#include<stdlib.h>
#include<time.h>
#define NUM 10
LRESULT CALLBACK Winproc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstanc,LPSTR lpCmdLine,int nShowCmd)
{
MSG msg;
static TCHAR szClassName[] = TEXT("::Bezier样条计算公式由法国雷诺汽车公司的⼯程师Pierm Bezier于六⼗年代提出");
HWND hwnd;
WNDCLASS wc;
wc.cbClsExtra =0;
wc.cbWndExtra =0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = Winproc;
wc.lpszClassName = szClassName;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW|CS_VREDRAW;
if(!RegisterClass(&wc))
{
MessageBox(NULL,TEXT("注册失败"),TEXT("警告框"),MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szClassName,szClassName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,SW_SHOWMAXIMIZED);
UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK Winproc(HWND hwnd,UINT message, WPARAM wparam,LPARAM lparam)
{
PAINTSTRUCT ps;
HDC hdc;
static POINT pt[NUM];
TEXTMETRIC tm;
static int cxClient,cyClient;
HPEN hpen;
int i,j,k,n,t;
switch(message)
{
case WM_CREATE:
static int cxchar;
hdc = GetDC(hwnd);
GetTextMetrics(hdc,&tm);
cxchar = tm.tmAveCharWidth;
ReleaseDC(hwnd,hdc);
case WM_SIZE:
cxClient = LOWORD(lparam);
cyClient = HIWORD(lparam);
return 0;
case WM_PAINT:
hdc = GetDC(hwnd);
srand(time(0));
Rectangle(hdc,0,0,cxClient,cyClient);
for(i=0; i<500; i++)
{
SelectObject(hdc,GetStockObject(WHITE_PEN));
PolyBezier(hdc,pt,NUM);
for(j=0; j<NUM; j++)
{
pt[j].x = rand()%cxClient;
pt[j].y = rand()%cyClient;
}
hpen = CreatePen(PS_INSIDEFRAME,3,RGB(rand()%256,rand()%256,rand()%256));
DeleteObject(SelectObject(hdc,hpen));
PolyBezier(hdc,pt,NUM);
for(k=0; k<50000000;k++);
}
for(i=0; i<100;i++)
{
Ellipse(hdc,rand()%cxClient,rand()%cyClient,rand()%cxClient,rand()%cyClient);
Pie(hdc,j=rand()%cxClient,k=rand()%cyClient,n=rand()%cxClient,t=rand()%cyClient,rand()%cxClient,rand()%cyClient,rand()%cxClient,rand()%cyClient) ; }
if((n=(n+j)/2)>cxchar*20) n=cxchar*20;
SetTextColor(hdc,RGB(rand()%256,rand()%256,rand()%256));
TextOut(hdc,n/2,(t+k)/2,TEXT("瑾以此向Pierm Bezier致敬!"),lstrlen(TEXT("瑾以此向Pierm Bezier致敬!")));
ReleaseDC(hwnd,hdc);
DeleteObject(hpen);
ValidateRect(hwnd,NULL);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,message,wparam,lparam); }。

相关文档
最新文档