ios 画线平滑_iOS 画贝塞尔曲线 连续曲线 平滑曲线 曲线图表

利用贝塞尔曲线画一段连续曲线

bezierDemo2.png

bezierDemo1.png

image.png

如果我们根据几个点画一条连续的曲线, 我们使用的方法是

- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2;

这个方法是由一个结束点和两个控制点作为参数, 画上一个点到这个结束点之间的一段曲线

首先求出控制点是画各个曲线的必须条件, 下面这个方法是求得控制点的方法, 需要我们传入4个点, 求出控制点1和控制点2

- (void)getControlPointx0:(CGFloat)x0 andy0:(CGFloat)y0

x1:(CGFloat)x1 andy1:(CGFloat)y1

x2:(CGFloat)x2 andy2:(CGFloat)y2

x3:(CGFloat)x3 andy3:(CGFloat)y3

path:(UIBezierPath*) path{

CGFloat smooth_value =0.6;

CGFloat ctrl1_x;

CGFloat ctrl1_y;

CGFloat ctrl2_x;

CGFloat ctrl2_y;

CGFloat xc1 = (x0 + x1) /2.0;

CGFloat yc1 = (y0 + y1) /2.0;

CGFloat xc2 = (x1 + x2) /2.0;

CGFloat yc2 = (y1 + y2) /2.0;

CGFloat xc3 = (x2 + x3) /2.0;

CGFloat yc3 = (y2 + y3) /2.0;

CGFloat len1 = sqrt((x1-x0) * (x1-x0) + (y1-y0) * (y1-y0));

CGFloat len2 = sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));

CGFloat len3 = sqrt((x3-x2) * (x3-x2) + (y3-y2) * (y3-y2));

CGFloat k1 = len1 / (len1 + len2);

CGFloat k2 = len2 / (len2 + len3);

CGFloat xm1 = xc1 + (xc2 - xc1) * k1;

CGFloat ym1 = yc1 + (yc2 - yc1) * k1;

CGFloat xm2 = xc2 + (xc3 - xc2) * k2;

CGFloat ym2 = yc2 + (yc3 - yc2) * k2;

ctrl1_x = xm1 + (xc2 - xm1) * smooth_value + x1 - xm1;

ctrl1_y = ym1 + (yc2 - ym1) * smooth_value + y1 - ym1;

ctrl2_x = xm2 + (xc2 - xm2) * smooth_value + x2 - xm2;

ctrl2_y = ym2 + (yc2 - ym2) * smooth_value + y2 - ym2;

[path addCurveToPoint:CGPointMake(x2, y2) controlPoint1:CGPointMake(ctrl1_x, ctrl1_y) controlPoint2:CGPointMake(ctrl2_x, ctrl2_y)];

}

比如我们要画出周二到周三之间的曲线, 我们需要传入周一, 周二, 周三, 周四, 4个点的坐标, 求得周二, 周三之间的两个控制点, 然后画出周二, 周三之间的曲线, 以此类推, 画出每一段曲线

但是会发现, 只有周一到周日7个点是不够画出6段曲线的, 所以我们需要在首尾各添加一个点(firstPoint, endPoint如下图所示)来求出周一周二间的曲线和周六周日间的曲线

image.png

下面结合代码进行说明

找出周一到周日对应点的x, y坐标

//初始化一个随机y的level

_pointYArray = @[@(1), @(4), @(1), @(5), @(2), @(3), @(5)];

//确定在view中的x, y准确的frame值

[_pointYArray enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

NSInteger objInter = 1;

if ([obj respondsToSelector:@selector(integerValue)]) {

objInter = [obj integerValue];

}

if ([obj respondsToSelector:@selector(integerValue)]) {

objInter = [obj integerValue];

if (objInter < 1) {

objInter = 1;

} else if (objInter > 5) {

objInter = 5;

}

}

CGPoint point = CGPointMake(_xAxisSpacing * idx + _axisToViewPadding + 30, CGRectGetHeight(self.frame) - _axisToViewPadding - (objInter - 1) * _yAxisSpacing - 11);

NSValue *value = [NSValue valueWithCGPoint:CGPointMake(point.x, point.y)];

[_pointsArray addObject:value];

}];

2.添加首尾两个点, 用于求出周一到周二和周六到周日之间控制点的坐标点

NSValue *firstPointValue = [NSValue valueWithCGPoint:CGPointMake(_axisToViewPadding, (CGRectGetHeight(self.frame) - _axisToViewPadding) / 2)];

[_pointsArray insertObject:firstPointValue atIndex:0];

NSValue *endPointValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetWidth(self.frame), (CGRectGetHeight(self.frame) - _axisToViewPadding) / 2)];

[_pointsArray addObject:endPointValue];

3.画曲线, 先将起点移动到周一坐标处, 根据firstPoint, 周一, 周二, 周三坐标画出周一到周二的曲线, 然后循环画出每一段曲线

/** 折线路径 */

UIBezierPath *path = [UIBezierPath bezierPath];

for (NSInteger i = 0; i < 6; i++) {

CGPoint p1 = [[_pointsArray objectAtIndex:i] CGPointValue];

CGPoint p2 = [[_pointsArray objectAtIndex:i+1] CGPointValue];

CGPoint p3 = [[_pointsArray objectAtIndex:i+2] CGPointValue];

CGPoint p4 = [[_pointsArray objectAtIndex:i+3] CGPointValue];

if (i == 0) {

[path moveToPoint:p2];

}

[self getControlPointx0:p1.x andy0:p1.y x1:p2.x andy1:p2.y x2:p3.x andy2:p3.y x3:p4.x andy3:p4.y path:path];

}

4.添加CAShapeLayer显示path

/** 将折线添加到折线图层上,并设置相关的属性 */

_bezierLineLayer = [CAShapeLayer layer];

_bezierLineLayer.path = path.CGPath;

_bezierLineLayer.strokeColor = [UIColor redColor].CGColor;

_bezierLineLayer.fillColor = [[UIColor clearColor] CGColor];

// 默认设置路径宽度为0,使其在起始状态下不显示

_bezierLineLayer.lineWidth = 3;

_bezierLineLayer.lineCap = kCALineCapRound;

_bezierLineLayer.lineJoin = kCALineJoinRound;

[self.layer addSublayer:_bezierLineLayer];

总结

画连续曲线要用到这个三次贝塞尔曲线的方法, 其他的画曲线的方法画出的均是不平滑的, 而画曲线要求我们得出每一段之间控制曲线的两个控制点, 由四个点确定控制点的坐标, 求控制点方法中的smooth_value =0.6, 是用来控制曲线锐度的, 网上大多数提供的数值为0.6

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/564427.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python中怎么判断字母大小写_python判断字符串是字母 数字 大小写(转载)

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼今天遇到的字符串处理的问题&#xff0c;记录一下方便使用str1 input(请输入一个字符&#xff1a;)#初始化字符、数字、空格、特殊字符的计数lowercase 0uppercase 0number 0space 0other 0for strs in str1:#如果在字符串中…

深度linux安装好上不了网,Deepin Linux 无法上网

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼我又用回2008了LINUX图形界面还是太慢 我的感觉太敏锐 虽然LINUX的图形界面的延迟 从你鼠标发出信号 到XSERVER的视觉呈现也就几百毫秒 但还是感觉比WINDOWS NT的效率差了几百倍 .用的越久感觉越明显.WINDOWS图形界面下的操控不管你…

php 伪静态 获取当前页面路径_织梦移动适配PHP获取当前页面URL地址方法

在做织梦网站开发时&#xff0c;会遇到获取当前URL并做PHP判断。比如地区站群PC端的移动适配功能&#xff0c;下面提供PHP通用移动端适配方法。PC首页路径&#xff1a;www.xx.com移动端首页路径&#xff1a;m.xx.com地区PC首页路径&#xff1a;beijing.xx.com地区移动端首页路径…

linux客户端 存活检测,Linux下客户端检测服务器的 heartbeat

客户端代码&#xff0c;和一般的客户端不一样#include#include#include#include#include#include#include#include#include#include#include #include #define MAXDATASIZE 100int main(){int sockfd,nbytes,serv_port;char buf_serv_ip[16],buf[260];struct sockaddr_in serv_…

lua打开浏览器并加载网页_Lua访问网页

示例例子&#xff0c;实现https方式&#xff0c;登录网站&#xff0c;访问某个网页&#xff0c;修改其中参数的功能。其中xx应用时候需要修改。require("curl")local ipList {"192.168.1.1","192.168.1.1",}--登陆function loginWeb(ip)c curl.…

linux jar和zip,Linux命令———zip和jar文件压缩解压

Linux命令———zip和jar文件压缩解压(1)ubuntu 使用unzip和zip压缩文件1.功能作用&#xff1a;解压缩zip文件2.位置&#xff1a;/usr/bin/unzip3.格式用法&#xff1a;unzip [-Z] [-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]4.主要参数-c 将解压缩的结果显示…

python去除中间空格只留一个_python 删除字符串中的连续空格只保留一个

Centos 6&period;5&lpar;64bit&rpar;上安装Vertica single node在Win8上使用虚拟机Virtualbox安装Centos6.5,想在上面安装vertica. 以下记录了我在安装的过程中遇到的问题与一些解决方案. 1.安装Centos的时候遇到了一个恼人的问题,即 ...大型网站系统架构实践(四)h…

安卓 linux找回内置存储,Android手机自带内部存储路径的获取

我有一台中兴的Android手机&#xff0c;型号是 ZTE U930HD&#xff0c;手机没有插入外置SD卡(也就是Micro SD Card&#xff0c;原名Trans-flash Card(TF卡)&#xff0c;2004年正式更名为Micro SD Card)&#xff0c;但是机身自带了一个内置存储卡(也就是eMMC存储&#xff0c;大小…

原生js获取document_原生JS常用API整理

Anchor 对象&#xff1a;指HTML超链接1.修改一个链接的文本&#xff0c;链接和target//html部分访问 Microsoft改变超链接的文本和 URL。也改变 target 属性。target 属性的默认设置是 "_self"&#xff0c;这意味着会在相同的窗口中打开链接。通过把 target 属性设置…

linux打包cpio命令例子,linux压缩命令——tar、cpio详解

常见的linux压缩方式&#xff1a;*.Z compress压缩*.gz gzip压缩*.bz2 bzip2压缩*.tar tar打包(没有压缩)*.tar.gz tar打包&#xff0c;并且经过gzip压缩*.tar.gz tar打包&#xff0c;并且经过bzip2压缩gzip、bzip2压缩是对单一文件压缩。下面就t…

flowjo汉化版_流式细胞分析软件FlowJo

FlowJo是一款专业的流式细胞分析软件&#xff0c;这款软件是流式领域最受推荐的一款专业分析软件&#xff0c;适合医学类的学生使用。软件能够帮助用户轻松了解了解细胞的状态变化, 拥有流动室和液流驱动系统&#xff0c;光电转换器和数据处理系统等先进的科学技术。软件特色&a…

c语言程序设计语言描述,C语言程序设计题目描述(详).txt

C语言程序设计题目描述(详).txtC01 pow1.05,n include void main float y1.05; int n1; FILE *p; /* * * * * * */ fprintfp,“d,.0f“,n,pow1.05,n; fclosep; C02 a11a002a11.aPaperdesign.dat include void main float a331.3,2.7,3.6,2,3,4.7,3,4,1.27; FILE *p; /* * * * *…

R语言smoothHR包_SmoothHR產品官方網站 全新體驗、正式上線 !

長期受許多國內外企業一致推薦及肯定的 SmoothHR 企業人資解決方案&#xff0c;新版網站正式上線了 ! 承襲 SmoothHR 備受肯定的視覺呈現&#xff0c;因應行動裝置的普遍運用&#xff0c;官方網站採用 RWD 響應式設計&#xff0c;帶給使用者跨裝置最佳的使用體驗 ! 並充分考慮使…

c程序设计语言 hello,Hello, World!

ch01-02-hello-world.mdcommit f63a103270ec8416899675a9cdb1c5cf6d77a498既然安装好了 Rust&#xff0c;我们来编写第一个 Rust 程序。当学习一门新语言的时候&#xff0c;使用该语言在屏幕上打印 Hello, world! 是一项传统&#xff0c;我们将沿用这一传统&#xff01;注意&am…

python object单引号变成双引号_Python学习第163课--Linux命令行中的单引号和双引号...

【每天几分钟&#xff0c;从零入门python编程的世界&#xff01;】我们都知道引号的作用就是为了引用&#xff0c;比如引用别人说的话&#xff0c;这句话就放在引号里面。而Linux命令行中的single quote(单引号)和dubble quote(双引号)有不同的作用。●双引号linux命令中双引号…

C语言条件循环语句执行步骤,C语言中for语句的执行过程是什么?

C语言中for语句的执行过程是&#xff1a;1、会先判断条件表达式是否成立&#xff0c;如果条件成立则执行中间循环体&#xff0c;执行完中间循环体后接着执行末尾循环体 &#xff1b;2、在执行完末尾循环体后对条件表达式再次判断&#xff0c;若条件还成立&#xff0c;则继续重复…

python平方数迭代器_Python三大神器之迭代器详解

我们将要来学习python的重要概念迭代和迭代器&#xff0c;通过简单实用的例子如列表迭代器和xrange。可迭代一个对象&#xff0c;物理或者虚拟存储的序列。list&#xff0c;tuple&#xff0c;strins&#xff0c;dicttionary&#xff0c;set以及生成器对象都是可迭代的&#xff…

c语言规范标准中英文,C语言中英文翻译资料.doc

C语言中英文翻译资料.docThe C Programming LanguageC is a high-level programming language developed by Dennis Ritchie and Brian Kernighan at Bell Labs in the mid-1970s. Although originally designed as a systems programming language, C has proved to be a powe…

lvm 扩展根目录_Lvm扩展根目录容量

2、新加一块硬盘&#xff0c;我的是sdb先创建物理卷[rootredhat6-3~]#fdisk/dev/sdbCommand(mforhelp):nCommandactioneextendedpprimarypartition(1-4)pPartitionnumber(1-4):1Firstcylinder(1-261,default1):(回车&#xff0c;默认将所有空间分配给第一个主分区)Usingdefault…

c语言趣味程序设计编程100例精解,c趣味编程100例

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include #include #include #include #include #include #include #include using namespace std;void z1();void z2();void z3();void z4();void z5();void z6();void z7();void z8();int c3(int, int);int draw(int(*)(double),…