Bezier曲线的生成算法参考代码
- 格式:doc
- 大小:84.00 KB
- 文档页数:4
Bezier曲线原理及实现代码(c++)一、原理:贝塞尔曲线于1962年,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。
贝塞尔曲线最初由Paul de Casteljau于1959年运用de Casteljau 算法开发,以稳定数值的方法求出贝塞尔曲线。
线性贝塞尔曲线给定点P0、P1,线性贝塞尔曲线只是一条两点之间的直线。
这条线由下式给出:且其等同于线性插值。
二次方贝塞尔曲线的路径由给定点P0、P1、P2的函数B(t) 追踪:。
TrueType字型就运用了以贝塞尔样条组成的二次贝塞尔曲线。
P0、P1、P2、P3四个点在平面或在三维空间中定义了三次方贝塞尔曲线。
曲线起始于P0走向P1,并从P2的方向来到P3。
一般不会经过P1或P2;这两个点只是在那里提供方向资讯。
P0和P1之间的间距,决定了曲线在转而趋进P3之前,走向P2方向的“长度有多长”。
曲线的参数形式为:。
现代的成象系统,如PostScript、Asymptote和Metafont,运用了以贝塞尔样条组成的三次贝塞尔曲线,用来描绘曲线轮廓。
一般化P0、P1、…、P n,其贝塞尔曲线即。
例如:。
如上公式可如下递归表达:用表示由点P0、P1、…、P n所决定的贝塞尔曲线。
则用平常话来说,阶贝塞尔曲线之间的插值。
一些关于参数曲线的术语,有即多项式又称作n阶的伯恩斯坦基底多项式,定义00 = 1。
点P i称作贝塞尔曲线的控制点。
多边形以带有线的贝塞尔点连接而成,起始于P0并以P n终止,称作贝塞尔多边形(或控制多边形)。
贝塞尔多边形的凸包(convex hull)包含有贝塞尔曲线。
线性贝塞尔曲线函数中的 t 会经过由 P 0 至P 1 的 B(t ) 所描述的曲线。
例如当 t=0.25 时,B(t ) 即一条由点 P 0 至 P 1 路径的四分之一处。
就像由 0 至 1 的连续 t ,B(t ) 描述一条由 P 0 至 P 1 的直线。
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,描述⼀条线性贝塞尔曲线。
绘制Bezier曲线编程及说明整体方案:(1)单击鼠标左键绘制控制点(不超过10个顶点),并自动连接为控制多边形。
(2)单击鼠标右键确定绘制Bezier曲线完毕。
(3)绘制时鼠标显示坐标。
(4)点击控制点可以改变Bezier曲线形状。
(5)可以使用鼠标或者键盘输入坐标绘制Bezier曲线。
关键技术:最小二乘法,曲线拟合,MFC框架编程Bezier曲线编程算法:// JjbView.cpp : implementation of the CJjbView class//#include "stdafx.h"#include "Jjb.h"#include "JjbDoc.h"#include "JjbView.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CJjbViewIMPLEMENT_DYNCREATE(CJjbView, CView)BEGIN_MESSAGE_MAP(CJjbView, CView)//{{AFX_MSG_MAP(CJjbView)ON_COMMAND(ID_BEZIER, OnBezier)ON_WM_LBUTTONDOWN()ON_WM_LBUTTONUP()ON_WM_MOUSEMOVE()ON_WM_RBUTTONDOWN()//}}AFX_MSG_MAP// Standard printing commandsON_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()/////////////////////////////////////////////////////////////////////////////// CJjbView construction/destructiondouble J(int n,int i);double C(int n,int i);double N(double u,int n);int JieCheng(int n);//构造函数CJjbView::CJjbView(){// TODO: add construction code herem_bIsChoosed=false;m_bStopDraw=false;m_bMakeSure=false;m_eChooseType=Bezier;while (m_vInputPoint.size()!=0){m_vInputPoint.pop_back();}while (m_vControlPoint.size()!=0){m_vControlPoint.pop_back();}while (m_vXiShu.size()!=0){m_vXiShu.pop_back();}}//析构函数CJjbView::~CJjbView(){while (m_vInputPoint.size()!=0){m_vInputPoint.pop_back();}while (m_vControlPoint.size()!=0){m_vControlPoint.pop_back();}while (m_vXiShu.size()!=0){m_vXiShu.pop_back();}}BOOL CJjbView::PreCreateWindow(CREATESTRUCT& cs) //定义窗口{// TODO: Modify the Window class or styles here by modifying// the CREATESTRUCT csreturn CView::PreCreateWindow(cs);}/////////////////////////////////////////////////////////////////////////////// CJjbView drawing// 刷新时绘图void CJjbView::OnDraw(CDC* pDC){CJjbDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// TODO: add draw code for native data hereGetClientRect(&rect);if (m_eMouseStatus==MouseMove&&m_bStopDraw==false){m_vInputPoint.push_back(m_cMovePoint);}CString str;CClientDC d(this);int i;if(m_bIsChoosed==true){if (m_bStopDraw==false){str.Format(" X=%d,y=%d ]",m_cMovePoint.x,m_cMovePoint.y);d.TextOut(m_cMovePoint.x+10,m_cMovePoint.y+10,str);}switch(m_eChooseType)//菜单选择{case Bezier: //选择后的窗口状态str.Format("Bezier曲线,点击右键表示确定,移动节点改变形状。
用四个顶点的函数表示bezier曲线代码Bezier曲线是一种广泛应用于计算机图形学中的数学曲线,由法国工程师和数学家Pierre Bezier于20世纪50年代发明。
它是一种参数曲线,通过数学公式描述曲线的控制点和曲线的形状。
在这篇文章中,我们将阐述如何用四个顶点的函数表示Bezier曲线代码。
第一步:定义控制点Bezier曲线使用控制点来确定曲线的形状。
曲线上的每个点都由相邻控制点之间的插值计算得出。
因此,我们需要声明四个控制点用于计算曲线。
这个过程可以用以下代码实现:```const p0 = {x: 0, y: 0};const p1 = {x: 50, y: 200};const p2 = {x: 150, y: -200};const p3 = {x: 200, y: 0};```这里我们定义了四个控制点,它们分别是 (0,0), (50,200), (150,-200)和 (200,0)。
第二步:计算Bezier曲线点的函数在本例中,我们将使用一个叫做“de Casteljau算法”的方法来计算Bezier曲线上的点。
de Casteljau算法是一种递归算法,它通过计算控制点之间的插值来生成Bezier曲线。
以下是一个用于计算Bezier曲线点的函数:```function getPointOnCurve(t) {const x = (1-t)*(1-t)*(1-t)*p0.x + 3*(1-t)*(1-t)*t*p1.x + 3*(1-t)*t*t*p2.x + t*t*t*p3.x;const y = (1-t)*(1-t)*(1-t)*p0.y + 3*(1-t)*(1-t)*t*p1.y + 3*(1-t)*t*t*p2.y + t*t*t*p3.y;return {x, y};}```上述代码会根据t值计算Bezier曲线上的一个点。
t值的范围是从0到1,它表示曲线上的位置。
bezier曲线表达式
贝塞尔曲线(Bezier Curve)是一种常用的数学曲线,用于计算机图形学和动画制作等领域。
贝塞尔曲线可以使用参数形式表示,也可以使用矢量表示。
贝塞尔曲线的矢量表示形式是:P(t) = ∑_{i=0}^{n} B_{i,n}(t) * P_i其中,P(t)表示曲线上的点,B_{i,n}(t)是贝塞尔基函数,P_i 是控制点。
n表示控制点的个数,t是一个参数,取值范围是[0,1]。
对于2次贝塞尔曲线,其基函数为:B_{0,2}(t) = 1-t^2, B_{1,2}(t) = 2t*(1-t), B_{2,2}(t) = t^2在参数t=0时,曲线起点为P_0;在参数t=1时,曲线终点为P_2。
对于3次贝塞尔曲线,其基函数为:B_{0,3}(t) = 1-t^3, B_{1,3}(t) = 3t*(1-t)^2, B_{2,3}(t) = 3t^2*(1-t), B_{3,3}(t) = t^3在参数t=0时,曲线起点为P_0;在参数t=1时,曲线终点为P_3。
对于更高次的贝塞尔曲线,其基函数可以递推得到。
此外,贝塞尔曲线的参数形式表示为:C(t) = ∑_{i=0}^{n} C_i * t^i其中,C_i是控制点,t是一个参数,取值范围是[0,1]。
该公式可用于绘制贝塞尔曲线。
实验(六) Bezier 曲线的算法实现一、实验目的根据曲线和曲面的基础知识和常用曲线的数学基础,对其算法进行程序设计,验证算法的正确性,并通过程序结果加深对常用曲线数学模型的理解。
二、实验任务(2学时)Bezier 曲线的算法实现;三、实验内容和实验步骤Bezier 曲线的算法实现(1)算法描述根据 Q(t)=∑P i•Bi,n(t) =∑P i•C i n t i (1-t)n-i并且 C i n =C(n,k)= C(n,k-1)(2)程序实现步骤:(工程名:BezierCurve )(ⅰ)C m n 的函数实现,定义成成员函数,命名为Multiply_n 。
C mn = =int Multiply_n(int m,int n){int i,j,a; if (m!=0) {a=1;for (i=m+1;i<=n;i++) //求(m+1)(m+2)…(n-1).na=a*i;for (j=1;j<=n-m;j++) //求(n-m)!和C m na=a/j; return a; } elsereturn 1;n! m!(n-m)! (n-m)! (m+1)(m+2)…(n-1).nni=0ni=0nn-k+1}(ⅱ)伯恩斯坦多项式Bm,n(t)的函数实现Bm,n (t)= C mnt m(1-t)n-mdouble Bernstein(int m,int n,double t){int i,j;double sum;sum=Multiply_n(m,n); //求C mnfor (i=1;i<=m;i++)sum=sum*t; // C mnt mfor (j=1;j<=n-m;j++)sum=sum*(1-t); // C mnt m(1-t)n-mreturn sum;}(ⅲ) 在OnDraw(CDC* pDC)函数中添加如下代码:int i,j,k,n=4; //n=4 表示四次Bezier曲线double curx,cury,t,b;double dt=0.01;intarray[6][2]={{50,50},{50,150},{100,130},{150,150},{200,140}, {250,350}};CPen PenRed(PS_SOLID,1,RGB(255,0,0));//定义红色笔CPen PenBlue(PS_SOLID,1,RGB(0,0,255));//定义蓝色笔 //首先绘出特征多边形pDC->SelectObject(&PenBlue);pDC->MoveTo(array[0][0],array[0][1]);for (i=0;i<=n;i++)pDC->LineTo(array[i][0],array[i][1]);//绘制Bezier曲线pDC->MoveTo(array[0][0],array[0][1]); //回到起点pDC->SelectObject(&PenRed);t=0.0;for (i=0;i<=(int)1/dt;i++){curx=0; cury=0;for(j=0;j<=n;j++){b=Bernstein(j,n,t);curx=curx+array[j][0]*b;cury=cury+array[j][1]*b;}pDC->LineTo(curx,cury);t=t+dt;}(3)编译、运行后查看结果,如图1所示。
计算机学院计算机科学与技术专业7 班学号3109006191姓名刘英双协作者教师评定实验四Bezier曲线生成1、实验目的与要求1.通过实验掌握理解并会自己编程实现二维Bezier曲线的画图;2.实现二维2、3、4阶Bezier曲线的绘制。
3.将生成算法以菜单或按钮形式集成到用户界面上。
4.坐标参数可以用鼠标或键盘输入。
2、实验方案1.实验1:○1Bezier曲线定义:给定n+1个控制顶点Pi(i=0~n) ,则Bezier曲线定义为:P(t)=∑Bi,n(t)Pi u∈[0,1]其中:Bi,n(t)称为基函数。
Bi,n(t)=Ci nti (1-t)n-iCi n=n!/(i!*(n-i)!)○2Bezier曲线性质✧端点性质:a)P(0)=P0, P(1)=Pn, 即:曲线过二端点。
b)P’(0)=n(P1-P0), P’(1)=n(Pn-Pn-1)即:在二端点与控制多边形相切。
✧凸包性:Bezier曲线完成落在控制多边形的凸包内。
✧对称性:由Pi与Pn-i组成的曲线,位置一致,方向相反。
✧包络性:Pn (t)=(1-t)Pn-1 (t)+tPn-1 (t)2.实验2✧实现了在菜单【曲线】->生成,弹出一个对话框,要求用户输入Bezier曲线的次数。
✧实现了在菜单【曲线】->计算,去掉点,计算生成Bezier曲线的控制点✧在界面中用鼠标左键点击,确定控制点,输入完控制点后,系统自动生成Bezier曲线3、实验结果和数据处理1.实验1实验结果:○1实验的代码如下:#include <GL/glut.h>#include <stdlib.h>#include <vector>using namespace std;struct Point {int x, y;};Point pt[4], bz[11];vector<Point> vpt;bool bDraw;int nInput;void CalcBZPoints(){float a0,a1,a2,a3,b0,b1,b2,b3;a0=pt[0].x;a1=-3*pt[0].x+3*pt[1].x;a2=3*pt[0].x-6*pt[1].x+3*pt[2].x;a3=-pt[0].x+3*pt[1].x-3*pt[2].x+pt[3].x;b0=pt[0].y;b1=-3*pt[0].y+3*pt[1].y;b2=3*pt[0].y-6*pt[1].y+3*pt[2].y;b3=-pt[0].y+3*pt[1].y-3*pt[2].y+pt[3].y;float t = 0;for(int i = 0; t<1.1; t+=0.1, i++){bz[i].x = a0+a1*t+a2*t*t+a3*t*t*t;bz[i].y = b0+b1*t+b2*t*t+b3*t*t*t;}}void ControlPoint(vector<Point> vpt){glPointSize(2);for(int i=0; i<vpt.size(); i++){glBegin (GL_POINTS);glColor3f (1.0f, 0.0f, 0.0f); glV ertex2i (vpt[i].x,vpt[i].y);glEnd ();}}void PolylineGL(Point *pt, int num){glBegin (GL_LINE_STRIP);for(int i=0;i<num;i++){glColor3f (1.0f, 1.0f, 1.0f);}glEnd ();}void myDisplay(){glClear(GL_COLOR_BUFFER_BIT);glColor3f (1.0f, 1.0f, 1.0f);if (vpt.size() > 0) {ControlPoint(vpt);}if(bDraw){PolylineGL(pt, 4);CalcBZPoints();PolylineGL(bz, 11);}glFlush();}void Init(){glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_SMOOTH);}void Reshape(int w, int h){glViewport(0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h); }void mouse(int button, int state, int x, int y){switch (button){case GLUT_LEFT_BUTTON:if (state == GLUT_DOWN){if (nInput == 0){pt[0].x = x;pt[0].y = 480 - y;nInput = 1;vpt.clear();vpt.push_back(pt[0]);glutPostRedisplay();// }else if (nInput == 1){pt[1].x = x;pt[1].y = 480 - y;vpt.push_back(pt[1]);nInput = 2;glutPostRedisplay();// }else if (nInput == 2){pt[2].x = x;pt[2].y = 480 - y;vpt.push_back(pt[2]);nInput = 3;glutPostRedisplay();// }else if (nInput == 3){pt[3].x = x;pt[3].y = 480 - y;vpt.push_back(pt[3]);nInput = 0;glutPostRedisplay();//}}break;default:break;}}int main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(640, 480);glutCreateWindow("Hello World!");Init();glutDisplayFunc(myDisplay);glutReshapeFunc(Reshape);glutMouseFunc(mouse);glutMainLoop();}○2实验的截图:2.实验2:○1实验代码附在代码文件夹中,关键代码如下:// Bezier.cpp : Defines the class behaviors for the application.//#include "stdafx.h"#include "Bezier.h"#include "MainFrm.h"#include "BezierDoc.h"#include "BezierView.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////BEGIN_MESSAGE_MAP(CBezierApp, CWinApp)//{{AFX_MSG_MAP(CBezierApp)ON_COMMAND(ID_APP_ABOUT, OnAppAbout)// NOTE - the ClassWizard will add and remove mapping macros here.// DO NOT EDIT what you see in these blocks of generated code!//}}AFX_MSG_MAP// Standard file based document commandsON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)// Standard print setup commandON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)END_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // CBezierApp constructionCBezierApp::CBezierApp(){// TODO: add construction code here,// Place all significant initialization in InitInstance}///////////////////////////////////////////////////////////////////////////// // The one and only CBezierApp objectCBezierApp theApp;///////////////////////////////////////////////////////////////////////////// // CBezierApp initializationBOOL CBezierApp::InitInstance(){AfxEnableControlContainer();// Standard initialization// If you are not using these features and wish to reduce the size// of your final executable, you should remove from the following// the specific initialization routines you do not need.#ifdef _AFXDLLEnable3dControls(); // Call this when using MFC in a shared DLL#elseEnable3dControlsStatic(); // Call this when linking to MFC statically#endif// Change the registry key under which our settings are stored.// TODO: You should modify this string to be something appropriate// such as the name of your company or organization.SetRegistryKey(_T("Local AppWizard-Generated Applications"));LoadStdProfileSettings(); // Load standard INI file options (including MRU)// Register the application's document templates. Document templates// serve as the connection between documents, frame windows and views.CSingleDocTemplate* pDocTemplate;pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CBezierDoc),RUNTIME_CLASS(CMainFrame), // main SDI frame windowRUNTIME_CLASS(CBezierView));AddDocTemplate(pDocTemplate);// Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo;ParseCommandLine(cmdInfo);// Dispatch commands specified on the command lineif (!ProcessShellCommand(cmdInfo))return FALSE;// The one and only window has been initialized, so show and update it.m_pMainWnd->ShowWindow(SW_SHOW);m_pMainWnd->UpdateWindow();return TRUE;}///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum { IDD = IDD_ABOUTBOX };// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)virtual void OnOK();//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg)//}}AFX_MSG_MAPEND_MESSAGE_MAP()// App command to run the dialogvoid CBezierApp::OnAppAbout(){CAboutDlg aboutDlg;aboutDlg.DoModal();}///////////////////////////////////////////////////////////////////////////// // CBezierApp message handlersvoid CAboutDlg::OnOK()// TODO: Add extra validation hereCDialog::OnOK();}○2实验结果截图:输入n:鼠标输入控制点:计算曲线:。
js 贝塞尔曲线算法贝塞尔曲线是一种通过控制点来生成平滑曲线的数学算法。
在Web开发中,它通常用于绘制图形、动画和页面效果。
本文将介绍JS 中的贝塞尔曲线算法,包括二次和三次曲线的实现方法和用法。
二次贝塞尔曲线算法二次贝塞尔曲线由三个点组成:起点P0,控制点P1和终点P2。
曲线在这些点之间平滑地弯曲。
下面是二次贝塞尔曲线的公式:B(t) = (1-t)^2 * P0 + 2 * t * (1-t) * P1 + t^2 * P2 其中,t的值从0到1,表示曲线上的点的位置。
B(t)就是曲线上的点的坐标。
在JS中,我们可以用下面的代码实现二次贝塞尔曲线:function quadraticBezier(t, p0, p1, p2) {var x = Math.pow(1-t,2) * p0.x + 2 * t * (1-t) * p1.x + Math.pow(t,2) * p2.x;var y = Math.pow(1-t,2) * p0.y + 2 * t * (1-t) * p1.y + Math.pow(t,2) * p2.y;return {x: x, y: y};}其中,t是曲线上的点的位置,p0、p1和p2是起点、控制点和终点。
三次贝塞尔曲线算法三次贝塞尔曲线由四个点组成:起点P0,控制点P1和P2以及终点P3。
曲线在这些点之间平滑地弯曲。
下面是三次贝塞尔曲线的公式:B(t) = (1-t)^3 * P0 + 3 * t * (1-t)^2 * P1 + 3 * t^2 * (1-t) * P2 + t^3 * P3其中,t的值从0到1,表示曲线上的点的位置。
B(t)就是曲线上的点的坐标。
在JS中,我们可以用下面的代码实现三次贝塞尔曲线:function cubicBezier(t, p0, p1, p2, p3) {var x = Math.pow(1-t,3) * p0.x + 3 * t * Math.pow(1-t,2) * p1.x + 3 * Math.pow(t,2) * (1-t) * p2.x + Math.pow(t,3) * p3.x; var y = Math.pow(1-t,3) * p0.y + 3 * t * Math.pow(1-t,2) * p1.y + 3 * Math.pow(t,2) * (1-t) * p2.y + Math.pow(t,3) * p3.y; return {x: x, y: y};}其中,t是曲线上的点的位置,p0、p1、p2和p3是起点、控制点和终点。