前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >挖一挖贝塞尔曲线那些事 原

挖一挖贝塞尔曲线那些事 原

作者头像
珲少
发布2018-08-15 15:04:30
4610
发布2018-08-15 15:04:30
举报
文章被收录于专栏:一“技”之长一“技”之长

挖一挖贝塞尔曲线那些事

一、前世今生

      贝塞尔曲线的最初设计是服务于工业设计,尤其应用与汽车曲线设计。随着计算机画图的应用广泛,若想在计算机上画出平滑精准的曲线并不是一件容易的事,贝塞尔曲线解决了这样的问题,贝塞尔虚线通过起始点与结束点来确定曲线的首尾,通过若干个控制点来确定曲线的走向。由于其由法国工程师皮埃尔·贝塞尔广泛推广,因此这种曲线被命名为贝塞尔曲线。

二、数学基础

      平面上的任意连续曲线可以通过伯恩斯坦多项式来进行逼近拟合,因此,当我们想在平面中画一条曲线的时候,如果可以模拟出此曲线的函数,则可以十分精准的控制计算机来描绘一系列曲线上的点来绘制曲线。贝塞尔曲线就是基于这样的数学基础。

      首先,对于一条贝塞尔曲线,其3要素分别是:起始点,结束点和控制点。其中曲线的起点在起始点,终点在结束点,曲线并不穿过控制点,控制点来掌握曲线的走向,控制点个数可以不定。

1、一阶贝塞尔曲线

      一阶贝塞尔曲线控制点的个数为0,只有起始点与结束点。其实一阶贝塞尔曲线就是一条从起始点到结束点的直线段。其公式如下:

上面公式中,P为曲线上的点,P0为起始点,P1为结束点。(对于平面上的点,分别用上面公式计算x,y坐标即可)。由于其公式为线性公式,所有这种贝塞尔曲线也被称为一阶贝塞尔曲线。下图可以很好的描述当t从0到1变化时,线段的绘制过程:

2、二阶贝塞尔曲线

      二阶贝塞尔曲线有一个控制点,假设起始点,控制点和结束点分别为P0、P1、P2。连接P0P1,P1P2,在区间0-1之间,在P0P1线段上取点M,在P1P2线段上取点N,使得P0M/P0P1=P1N/P1P2,找到线段MN上一点Q,同时使得MQ/QN=P0M/P0P1=P1N/P1P2,所有Q点的集合即为所求贝塞尔曲线。上面的描述有些抽象,使用数学推导就义一目了然了,公式推导如下:

绘图过程如下:

3.高阶贝塞尔曲线

      有了一阶与二阶的基础,高阶贝塞尔曲线也是通过相同的方式来推导,一个通用的递推公式如下:

三阶和四阶的绘制过程演示如下:

三、iOS中的贝塞尔曲线的应用

    虽然贝塞尔曲线在很多开发领域都十分容易实现,由于我对iOS开发比较熟,并且上面的曲线绘制示例也是我通过iOS程序实现的。这里就对在iOS中应用贝塞尔曲线进行简单的讨论,首先CoreGraphics核心图形框架中提供了CGPath可以直接创建贝塞尔曲线,系统支持的贝塞尔曲线函数有二阶与三阶。前面有博客专门讨论,这里就不再赘述,地址如下:

https://cloud.tencent.com/developer/article/1186307

这里主要列举UIKit框架中的UIBezierPath类。

代码语言:javascript
复制
//构造方法
+ (instancetype)bezierPath;
//使用矩形进行构造
+ (instancetype)bezierPathWithRect:(CGRect)rect;
//使用圆角矩形进行构造
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
//创建圆角矩形贝塞尔路径 并设置圆角半径
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; 
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;
//使用圆弧创建
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;
//使用CGPath创建
+ (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;

//CGPath对象
@property(nonatomic) CGPathRef CGPath;

//将路径移动到某个点
- (void)moveToPoint:(CGPoint)point;
//添加一天线
- (void)addLineToPoint:(CGPoint)point;
//添加一个二阶贝塞尔曲线段
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;
//添加一个三阶贝塞尔曲线段
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;
//添加圆弧
- (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;
//关闭路径
- (void)closePath;
//移除所有点
- (void)removeAllPoints;
//添加一段路径
- (void)appendPath:(UIBezierPath *)bezierPath;
//对路径进行逆向
- (UIBezierPath *)bezierPathByReversingPath;
//进行transform变换
- (void)applyTransform:(CGAffineTransform)transform;
//路径是否为空
@property(readonly,getter=isEmpty) BOOL empty;
//尺寸
@property(nonatomic,readonly) CGRect bounds;
//当前点
@property(nonatomic,readonly) CGPoint currentPoint;
//判断是否包含某个点
- (BOOL)containsPoint:(CGPoint)point;

//设置线宽
@property(nonatomic) CGFloat lineWidth;
//设置线帽风格
@property(nonatomic) CGLineCap lineCapStyle;
//设置折点风格
@property(nonatomic) CGLineJoin lineJoinStyle;
@property(nonatomic) CGFloat miterLimit;
@property(nonatomic) CGFloat flatness;
//奇偶规则
@property(nonatomic) BOOL usesEvenOddFillRule;
//进行虚线设置
- (void)setLineDash:(nullable const CGFloat *)pattern count:(NSInteger)count phase:(CGFloat)phase;
- (void)getLineDash:(nullable CGFloat *)pattern count:(nullable NSInteger *)count phase:(nullable CGFloat *)phase;
//进行填充绘制
- (void)fill;
//进行路径绘制
- (void)stroke;

四、示例程序

      下面是一个iOS平台的演示小Demo,使用它可以动态进行贝塞尔曲线的绘制并观察到辅助线与绘制过程,可以灵活的配置绘制的速度和控制点:

Github地址如下:

https://github.com/ZYHshao/Bezel

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017/08/23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 挖一挖贝塞尔曲线那些事
    • 一、前世今生
      • 二、数学基础
        • 1、一阶贝塞尔曲线
        • 2、二阶贝塞尔曲线
        • 3.高阶贝塞尔曲线
      • 三、iOS中的贝塞尔曲线的应用
        • 四、示例程序
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档