精华内容
参与话题
问答
  • Bezier曲线原理及其代码实现

    千次阅读 2018-12-05 15:49:32
    Bezier曲线原理及实现代码(c++)  一、原理:  贝塞尔曲线于1962年,由法国工程师皮埃尔?贝塞尔(Pierre B?zier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由 Paul de Casteljau ...

    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、…、Pn,其贝塞尔曲线即


    例如 :


    如上公式可如下递归表达: 用 
     表示由点 P0、P1、…、Pn 所决定的贝塞尔曲线。则

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

     

    一些关于参数曲线的术语,有


     

    即多项式

    又称作 n 阶的伯恩斯坦基底多项式,定义 00 = 1。

    点 Pi 称作贝塞尔曲线的控制点。多边形以带有线的贝塞尔点连接而成,起始于 P0 并以 Pn 终止,称作贝塞尔多边形(或控制多边形)。贝塞尔多边形的凸包(convex hull)包含有贝塞尔曲线。

     

     

     

     

     

    线性贝塞尔曲线函数中的 t 会经过由 P0 至P1 的 B(t) 所描述的曲线。例如当 t=0.25 时,B(t) 即一条由点 P0 至 P1 路径的四分之一处。就像由 0 至 1 的连续tB(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)P0+tP1 , 
    矩阵表示为:
       。
    P(t)=(1-t)2P0+2t(1-t)*P1+t2P2, 
    矩阵表示为:
       。

     

    P(t)=(1-t)3P0+3t(1-t)2P1+3t2(1-t)P2+t3P3 
    矩阵表示为:
    , 
    (6-3-2) 
     。 
    在(6-3-2)式中,Mn+1是一个n+1阶矩阵,称为n次Bezier矩阵。
     (6-3-3)

    其中,

    利用(6-3-3)式,我们可以得到任意次Bezier矩阵的显式表示,例如4次和5次Bezier矩阵为:

     
    可以证明,n次Bezier矩阵还可以表示为递推的形式:
     (6-3-4)
     

    二、算法(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) 

     
        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); 

    展开全文
  • 作为一个有只志向的码农,除了知道一些基本的知识够自己努力搬砖以外,还应该get一些更炫酷的技能,用更优雅的姿势进行搬砖;想要实现一些十分炫酷的效果,贝塞尔曲线就必须进行一些研究了; 最近一段时间,我对贝塞尔...

      作为一个有只志向的码农,除了知道一些基本的知识够自己努力搬砖以外,还应该get一些更炫酷的技能,用更优雅的姿势进行搬砖;想要实现一些十分炫酷的效果,贝塞尔曲线就必须进行一些研究了;
    最近一段时间,我对贝塞尔曲线进行了部分的研究,因此就打算写贝塞尔曲线系列的文章来记录自己的研究;

    规矩我都懂 !

      我明白,必须先上图,要不然大家都没兴趣看下去

    先看比较简单的,贝塞尔曲线的一阶和二阶的应用

    这里写图片描述

      看到二阶的贝塞尔曲线有没有感觉很眼熟,没错,360的下火箭弹射时候的小弹弓,还有滑动控件的阴影提示;以前的时候很多小伙伴跟我说这要计算多少数据啊,完全没办法实现啊,现在有了贝塞尔曲线,可以很简单的实现这一个功能;
      不过完全不能这样满足啊,接下来还有更复杂一些的曲线

    这里写图片描述

      没错,这个就是三阶的使用,有没有感觉路线更加复杂,不过还好,使用贝塞尔去玩完全可以轻松实现;对了,还有一个心在沿着曲线移动,看到这里,小伙伴们肯定会想到满屏幕的心在飞的场景,放心,这个我也实现了,在接下来的文章里,我会一一进行讲解;

    这里写图片描述

    图片看完了,现在简单了解贝塞尔曲线

    Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。 曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。 1962年,法国数学家Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。

    以下公式中:B(t)为t时间下 点的坐标;

    P0为起点,Pn为终点,Pi为控制点

    一阶贝塞尔曲线(线段):

    这里写图片描述

    意义:由 P0 至 P1 的连续点, 描述的一条线段

    二阶贝塞尔曲线(抛物线):

    这里写图片描述

    原理:由 P0 至 P1 的连续点 Q0,描述一条线段。
    由 P1 至 P2 的连续点 Q1,描述一条线段。
    由 Q0 至 Q1 的连续点 B(t),描述一条二次贝塞尔曲线。

    经验:P1-P0为曲线在P0处的切线。

    三阶贝塞尔曲线:

    这里写图片描述

    通用公式:

    这里写图片描述

    利用贝塞尔曲线的这些特性,我们可以画出很多炫酷的曲线,所以贝塞尔曲线还是值得我们去研究学习的;

    但是这些完全记不住啊!!!

    没关系,可以很负责的说,我也是!!!!!

    上面的曲线完全是来自http://blog.csdn.net/tianhai110/article/details/2203572

    所以,如果你的数学和我一样是体育老师教的,就忘记这些吧,跟我一起看看android中是实现一条贝塞尔曲线的,android已经帮我们实现好了,剩下的就需要我们进行简单使用,具体的使用,就看下一篇中讲解

    最后附上源码:https://github.com/sangxiaonian/BezierIntroduce.git

    展开全文
  • 源码下载: “贝赛尔曲线”是由法国数学家Pierre Bézier所发明,由此为计算机矢量图形学奠定了基础。它的主要意义在于无论是直线或曲线都能在数学上予以描述。 算法的基本原理: 贝塞尔曲线贝塞尔曲线是计算机...

    源码下载:点我下载

    贝赛尔曲线”是由法国数学家Pierre Bézier所发明,由此为计算机矢量图形学奠定了基础。它的主要意义在于无论是直线或曲线都能在数学上予以描述。

    算法的基本原理:

    贝塞尔曲线贝塞尔曲线是计算机图形图像造型的基本工具,是图形造型运用得最多的基本线条之一。它通过控制曲线上的四个点(起始点、终止点以及两个相互分离的中间点)来创造、编辑图形。其中起重要作用的是位于曲线中央的控制线。这条线是虚拟的,中间与贝塞尔曲线交叉,两端是控制端点。移动两端的端点时贝塞尔曲线改变曲线的曲率(弯曲的程度);移动中间点(也就是移动虚拟的控制线)时,贝塞尔曲线在起始点和终止点锁定的情况下做均匀移动。注意,贝塞尔曲线上的所有控制点、节点均可编辑。这种“智能化”的矢量线条为艺术家提供了一种理想的图形编辑与创造的工具。

    以下公式中:B(t)为t时间下 点的坐标;

    P0为起点,Pn为终点,Pi为控制点

    一阶贝塞尔曲线(线段):



    意义:由 P0 至 P1 的连续点, 描述的一条线段

    二阶贝塞尔曲线(抛物线):



    原理:由 P0 至 P1 的连续点 Q0,描述一条线段。
    由 P1 至 P2 的连续点 Q1,描述一条线段。
    由 Q0 至 Q1 的连续点 B(t),描述一条二次贝塞尔曲线。

    经验:P1-P0为曲线在P0处的切线。

    三阶贝塞尔曲线:


    通用公式:


    高阶贝塞尔曲线:

    4阶曲线:


    5阶曲线:


    代码:

    typedef struct
    	{
    		double x;
    		double y;
    	}DPoint;
    DPoint points[100];
    void CBezierView::DrawBzier(DPoint * p)
    {
    	if (n<= 0)
    		return;
    	if((p[n].x<p[0].x+1)&&(p[n].x>p[0].x-1)&&(p[n].y<p[0].y+1)&&(p[n].y>p[0].y-1))
    	{
    		pDC->SetPixel(p[0].x, p[0].y, RGB(0,0,255));
    		return;
    	}
    	DPoint *p1;
    	p1 = new DPoint[n+1];
    	int i, j;
    	p1[0] = p[0];
    	for(i=1; i<=n; i++)
    	{
    		for(j=0; j<=n-i;j++)
    		{
    			p[j].x = (p[j].x + p[j+1].x)/2;
    			p[j].y = (p[j].y + p[j+1].y)/2;
    		}
    		p1[i] = p[0];
    	}
    	DrawBzier(p);
    	DrawBzier(p1);
    	delete p1;
    }
    可以看出代码是使用递归的算法,找中点,然后在达到
    if((p[n].x<p[0].x+1)&&(p[n].x>p[0].x-1)&&(p[n].y<p[0].y+1)&&(p[n].y>p[0].y-1))
    的情况下留下该点,然后当所有的点都出来之后就是贝赛尔曲线了。

    实现的图片


    其中点击ADD可以增加点,最多99个,点击MOVE可以移动点。

    代码很简单,理解也不难。

    如果有什么问题,还望指出。谢谢

    展开全文
  • 贝塞尔曲线——cubic-bezier详解

    万次阅读 2017-12-13 19:03:09
    在animation和transition两个属性中,cubic-bezier是控制变化的速度曲线,下面我们来了解下什么是cubic-bezier。cubic-bezier称为三次贝塞尔曲线,主要是生成速度曲线的函数,规定是cubic-bezier(<x1>,<y1&...

    在animation和transition两个属性中,cubic-bezier是控制变化的速度曲线,下面我们来了解下什么是cubic-bezier。

    cubic-bezier称为三次贝塞尔曲线,主要是生成速度曲线的函数,规定是cubic-bezier(<x1>,<y1>,<x2>,<y2>) .
    这里写图片描述这里写图片描述

    从上图中我们可以看到,cubic-bezier有四个点:
    两个默认的,即:P0(0,0),P3(1,1);
    两个控制点,即:P1(x1,y1),P2(x2,y2)
    注:X轴的范围是0~1,超出cubic-bezier将失效,Y轴的取值没有规定,但是也不宜过大。
    我们只要调整两个控制点P1和P2的坐标,最后形成的曲线就是动画曲线。

    下面以我们常用到的曲线为例:
    1、linear,即cubic-bezier(0,0,1,1) / cubic-bezier(1,1,0,0),左边cubic-bezier曲线,右边浏览器动画曲线展示。下同。
    这里写图片描述这里写图片描述

    2、ease,即cubic-bezier(0.25,0.1,0.25,1)
    这里写图片描述这里写图片描述

    3、ease-in,即cubic-bezier(0.42,0,1,1)
    这里写图片描述这里写图片描述

    4、ease-out,即cubic-bezier(0,0,0.58,1)
    这里写图片描述这里写图片描述

    5、ease-in-out,即这里写代码片
    这里写图片描述这里写图片描述

    6、随机示例1:cubic-bezier(0.68,-0.55,0.27,0.55)
    这里写图片描述这里写图片描述

    7、随机示例2:cubic-bezier(0.17,0.86,0.73,0.14)
    这里写图片描述这里写图片描述

    更多缓动函数请查看:
    https://easings.net/zh-cn#


    本文属转载,在原文基础上稍作修改。
    转自:http://www.jianshu.com/p/d999f090d333

    展开全文
  • Bezier、B样条曲线曲面

    万次阅读 多人点赞 2017-01-19 22:09:43
    这里只列出核心,具体原理参看底部参考文献Bezier曲线 三次Bezier曲线 第一个控制点和最后一个控制点在曲线上: 两端点的切矢方向与控制多边形(特征多边形)的第一条和最后一条边一致: Bezier曲线...
  • Bezier Curve

    2019-04-08 17:05:21
    Bezier Curve
  • Bezier

    2020-01-17 17:06:41
    浅谈贝塞尔(Bezier)曲线的原理以及VC代码实现 Bezier曲线原理 诞生缘由: 就是有一位大神觉得画曲线工具太难用,对比微软的画图工具和其他专业的画图工具,他就越想越恼火,为什么我就不能修改画错的曲线呢? 为什么...
  • n阶bezier曲线 通用公式说明和应用

    千次阅读 2018-09-08 02:57:00
    今天,孤陋寡闻数学不好的我,才知道n阶bezier 曲线是有一个通用公式的。 我先把这个公式截图放在这里,留作备忘 感觉就这么一个公式,说的就比较明确了,用代码实现起来也比较简单。 稍微解释一下: 上面...
  • 贝塞尔曲线简单介绍

    万次阅读 多人点赞 2019-08-09 16:53:51
    什么是贝塞尔曲线? Bézier curve(贝塞尔曲线) 是应用于二维图形应用程序的数学曲线。 曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。 1962年,法国数学家Pierre B...
  • Bezier曲线原理—动态解释

    千次阅读 2016-03-17 11:15:37
    贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们...
  • 在Matlab GUI中实现了Bezier任意阶数曲线和曲面的绘制。曲线可使用鼠标生成控制点,控制点可随意拖动;也可手动输入控制点坐标。曲面控制点信息可使用xls文件导入,也可手动输入控制点坐标。 程序使用Matlab GUI...
  • bezier曲线和bezier曲面

    千次阅读 2010-11-10 16:57:00
    如果想理解贝塞尔曲面没有对其数学基本的认识是很难的,如果你不愿意读这一部分或者你已经知道了关于她的数学知识你可以跳过。首先我会描述贝塞尔曲线再介绍生成贝塞尔曲面。 奇怪的是,如果你用过一...
  • 使用OpenGL绘制Bezier曲线

    热门讨论 2014-04-05 21:24:48
    本程序主要通过调用OpenGL库中的基础函数实现了Bezier曲线的绘制,绘制原理是利用递推公式求解Bernstein多项式,进而求解出Bezier曲线上对应点的坐标值,然后连接这些点绘制出Bezier曲线。点击左键选择顶点,点击...
  • Bezier曲线切割

    2020-07-21 16:26:07
    目标:在unity中展示Bezier曲线。 贝塞尔曲线原理 用代码实现 bezier数学公式 Bezier公式(一般参数公式) 注解: 阶贝兹曲线可如下推断。给定点P0、P1、…、Pn,其贝兹曲线即: 如上公式可如下递归表达:...
  • Bezier样条

    2016-09-03 11:23:33
    这就是贝塞尔(Bezier)样条,加上两条直线有助于理解,windows中有画Bezier样条的函数,就是PolyBezier; 不知道函数怎么用,可以查阅微软的官方帮助文档msdn,下面是msdn的解释 BOOL PolyBezier( HD
  • bezier曲线

    2020-05-28 22:17:29
    Bezier曲线有暴力和递推两种方法,但是暴力太不雅观而且组合复杂度太高,于是采用了递推这个方法。首先是可以利用算子的方法证明出来p(t)= (1-t)*Σ(i=0,n-1)C(n-1,i)ti*(1-t)(n-1-i)p(i)+ tΣ(i=1,n)C(n,i)ti*(1-...
  • 代码 /*INTRODUCTION // Mouse: // - LEFT button: // 1. add/move a control points // 2. with keyboard DELETE: delete control points // - RIGHT button: // 1. PRESS: select a control points // 2....//
  • 文档包括bezier曲线曲面生成算法 的原理公式说明 以及编程实现。 文档的项目“Bezier”是使用 Microsoft VC++ 6.0 实现的,当然只要是配置好 OpenGl环境的C++平台都可以使用,把关键cpp代码复制即可。
  • Bezier曲线曲面的C++实现

    万次阅读 2015-11-14 19:53:14
    Bezier曲线曲面的C++实现,初期版本,只实现了初始化和求点。
  • 在上篇博客中介绍了直线的制作,下面继续曲线的制作流程,曲线算法很多,

空空如也

1 2 3 4 5 ... 20
收藏数 15,877
精华内容 6,350
关键字:

bezier