IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 运用贝塞尔曲线绘制笔锋效果 -> 正文阅读

[移动开发]运用贝塞尔曲线绘制笔锋效果

“笔锋”是指用户通过手指、或者鼠标工具在屏幕上拖动模拟真实场景下用笔写文字的效果,文字的书写过程是会根据我们书写的速度实时变化的,通过笔锋算法我们能够模拟出真实场景下书写文字时的线条变化以及结束时的带笔效果。

那么我们如何来绘制笔锋线条呢

本文将通过介绍贝塞尔曲线的基本概念以及笔锋轨迹算法,来给大家详细解答如何运用贝塞尔曲线实现绘制笔锋的功能。

一、关于贝塞尔曲线

首先,什么是贝塞尔曲线呢?

维基百科上介绍,贝塞尔曲线于1962年,由法国工程师皮埃尔·贝兹(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由保尔·德·卡斯特里奥于1959年运用德卡斯特里奥算法开发,以稳定数值的方法求出贝塞尔曲线。

数学数值分析领域中,贝塞尔曲线(英语:Bézier curve)是计算机图形学中相当重要的参数曲线。更高维度的广泛化贝塞尔曲线就称作贝兹曲面,其中贝兹三角是一种特殊的实例。

二、UIBezierPath?的基本使用

接下来为大家讲解一下如何生成一条贝塞尔曲线路径以及笔锋的绘制原理。

这里我们通过 iOS 的 UIBezierPath 类来举例说明:

UIBezierPath 是 CGPathRef 数据类型的封装。path 如果是基于矢量形状的,都用直线和曲线段去创建。

如下 UIBezierPath 的API 我们可以看到,系统已提供了丰富的接口供我们使用来绘制一条贝塞尔轨迹:

UIKIT_EXTERN API_AVAILABLE(ios(3.2)) @interface UIBezierPath : NSObject<NSCopying, NSSecureCoding>


+ (instancetype)bezierPath;
+ (instancetype)bezierPathWithRect:(CGRect)rect;
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; // rounds all corners with the same horizontal and vertical radius
+ (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;
+ (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;


- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;


// Returns an immutable CGPathRef which is only valid until the UIBezierPath is further mutated.
// Setting the path will create an immutable copy of the provided CGPathRef, so any further mutations on a provided CGMutablePathRef will be ignored.
@property(nonatomic) CGPathRef CGPath;
- (CGPathRef)CGPath NS_RETURNS_INNER_POINTER CF_RETURNS_NOT_RETAINED;

// Path construction
- (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 API_AVAILABLE(ios(4.0));
- (void)closePath;

- (void)removeAllPoints;

// Appending paths
- (void)appendPath:(UIBezierPath *)bezierPath;

如何实例化一条 UIBezierPath 路径,下图举例了实现一条二阶贝塞尔曲线 Path:

CGFloat speedFactor//速度因子 用来配合距离求得速度 
CGFloat distance//两点间的距离 
CGFloat speed = distance ?? speedFactor;//求得速度

三、笔锋实现

通过上面的介绍我们已经了解了 UIBezierPath 的大致用法,以及如何生成一条贝塞尔路径出来,现在我们来介绍一下关于如何通过 UIBezierPath 来生成一条笔锋路径。

我们知道要实现笔锋需要根据绘制速度来实现路径的宽度变化,可以根据我们知道的距离/时间 可以得到速度,如下示例代码:

CGFloat speedFactor//速度因子 用来配合距离求得速度 
CGFloat distance//两点间的距离 
CGFloat speed = distance ?? speedFactor;//求得速度

通过上面求得的速度值,我们可以用来求取我们的路径当前的线宽 LineWidth(此处求线宽的函数就不做具体描述,这里可以根据具体的业务需求变化),我们拿到线宽就能够求得当前点的左右2个点 leftPoint 和 rightPoint。

如下图所示:

通过以上方式我们就能求得每一个点的左右2点了,因此屏幕每采集2个点就能够求的矩形的4个点,通过4个点连线得到一个矩形,然后通过矩形的拼接形成一条笔锋路径。

///构建矩形路径
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint:leftPoint1];
[bezierPath addLineToPoint:leftPoint2];
[bezierPath addLineToPoint:rightPoint2];
[bezierPath addLineToPoint:rightPoint1];
[bezierPath addLineToPoint:leftPoint1];
[bezierPath closePath];

现在假设屏幕采集到的点为 startPoint、point1、point2、endPoint,如何通过这四点绘制出一条笔锋路径呢?

如下图所示:

通过上图我们可以看出我们实际显示出来的 path 应该是 startPoint->leftPoint1->leftPoint2->endPoint->rightPoint2->rightPoint1->startPoint 这么一条 path,如果不加笔锋我们实际path应该是startPoint->point1->point2→endPoint.

轨迹优化

当然我们还能优化上图中的轨迹,让轨迹看起来更加的顺滑,我们可以使用二阶贝塞尔曲线来连接2点,轨迹看起来更加的平滑。

系统也提供了对应的 api 供我们使用:

///三阶贝塞尔
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;
///二阶贝塞尔
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;

通过上述的方法实现效果如下图所示:

?四、结语

本文对 iOS 中的 UIBezierPath 的用法及使用场景进行了基本的介绍,我们可以看到 UIBezierPath 提供了很多便捷的 API 方法,我们在实际的场景中如果熟练的运用这些 API ,结合我们自身的一些算法能够容易的绘制出各种图形。???????

?

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-10-09 16:23:57  更:2021-10-09 16:25:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:48:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码