必威体育Betway必威体育官网
当前位置:首页 > IT技术

贝塞尔曲线的绘制方法

时间:2019-09-06 21:41:59来源:IT技术作者:seo实验室小编阅读:72次「手机版」
 

贝塞尔

 两年前调试全向轮底盘的时候,曾经用到过贝塞尔曲线做路径规划。今天同学突然问起这个东西,回查了一下当时的代码,觉得有必要写个博客备忘一下。

 在数学的数值分析领域中,贝塞尔曲线是计算机图形学中相当重要的参数曲线。更高维度的广泛化贝济埃曲线就称作贝济埃曲面,其中贝济埃三角是一种特殊的实例。

 贝塞尔曲线于1962年,由法国工程师皮埃尔·贝济埃(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由Paul de Casteljau于1959年运用de Casteljau算法开发,以稳定数值的方法求出贝塞尔曲线。

接下来简单介绍贝塞尔曲线的绘制方法。如下图,假设给定了控制点P0,P1,P2。这里我们需要做辅助点Q0和Q1,使得:

P0Q0:P0P1=P1Q1:P1P2=t,这里0≤t≤1。现在,我们可以简单理解为三个控制点P0,P1,P2  “降维”  成了两个控制点Q0,Q1。按照同样的方法,再取辅助点B使得Q0B:Q0Q1=t,这里的 t 和上次 "降维"时的 t 是相等的。现在,我们已经降维成了只有一个点,那么这个点B就是该贝塞尔曲线中的一点

                          

推广一下,我们考虑多个控制点的情景。对于4、5、6。。。n个控制点,首先选定一个比例 t ,以此按比例降维直到只有一个点,这个点就是比例 t 时贝塞尔曲线上的点。当把 t 从0到1按照一定比例依次选取时,就能绘制出一个贝塞尔曲线。

                

  六个控制点的情形:

                                                       

根据之前的描述,绘制贝塞尔曲线的过程可以用如下公式表述:

式中,j是降了多少次维,i是第i个控制点。由于每降维一次,控制点就减少一个,所以i的取值范围是(0,n-j)。

C#程序如下:

        //==========================根据t获取贝塞尔曲线上一个点===========================
        const int ControlPointNum = 10 ; //控制点数目
        Point[] ControlPoint = new Point[ControlPointNum]; //控制点
        Point[] WorkPoint = new Point[ControlPointNum];  //一块用于存放临时数据空间
        /// <summary>
        /// 获取本轮计算终点坐标
        /// </summary>
        /// <param name="t">贝塞尔曲线生成过程中的百分比</param>
        /// <param name="n">本层迭代控制点数目</param>
        /// <returns></returns>
        Point GetfinalPoint(double t, int n)
        {
            if (n == 1)
            {
                return WorkPoint[0];
            }
            else
            {
                //计算下一阶的贝塞尔控制点
                for (int i = 0; i < n - 1; i++)
                {
                    WorkPoint[i].X = (int)(WorkPoint[i].X * (1 - t) + WorkPoint[i + 1].X * t);
                    WorkPoint[i].Y = (int)(WorkPoint[i].Y * (1 - t) + WorkPoint[i + 1].Y * t);
                }
                //进入下一层
                return GetFinalPoint(t, n - 1);
            }
        }
 //==========================根据t绘制曲线======================================
            for(int i=0;i<256;i++)
            {
                for (int j = 0; j < ControlPointNum; j++)//赋值控制点坐标至临时工作空间
                {
                    WorkPoint[j] = ControlPoint[j];
                }
                double t = (double)i/255.0;
                Point FinalPoint = GetFinalPoint(t,ControlPointNum);
                DrawPoint(FinalPoint);                  //调用绘图函数
            }

效果:

                                                

相关阅读

产品流程设计:如何绘制业务流程图?

业务流程图是最常见的图表之一,能看懂读懂是必修课,能绘制便是非常重要的选修课。在实际生活中,我们会碰到各种各样的流程。比如你去

UML图绘制的注意点和实例分析

先百度一下,Unified Modeling Language (UML)又称统一建模语言或标准建模语言,是始于1997年一个OMG标准,它是一个支持模型化和软件系

Android SurfaceView的绘制详解

在Android系统中,有一种特殊的视图,称为SurfaceView,它拥有独立的绘图表面,即它不与其宿主窗口共享同一个绘图表面。由于拥有独立的绘

制作人人喜欢的流程图,三步教会你绘制大厂流程图(第二

继帮大家解决了如何绘制流程图的难题后,本篇作者将帮助大家学习:如何绘制出研发喜欢看、运营看得懂的流程图。学习了上一篇“流程图

如何进行市场细分并初步绘制用户画像?

通过市场细分,企业可以按照某种分类标准,将总体市场中的用户划分成若干个用户群体。市场细分概述市场细分( Market Segmentation)

分享到:

栏目导航

推荐阅读

热门阅读