iOS-OC-Bézier Path简介

2023-10-25 18:30
文章标签 ios 简介 path oc zier

本文主要是介绍iOS-OC-Bézier Path简介,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

添加线条和多边形

  • Bézier的线和多边形是使用moveToPoint:addLineToPoint:方法逐点构建的简单形状。moveToPoint:方法设置你想要创建的形状的起点。从这一点开始,使用addLineToPoint:方法创建形状的线条。您可以连续创建这些线,每条线都是在上一个点和您指定的新点之间形成的。
- (void)drawRect:(CGRect)rect {UIBezierPath *bezierPath = [UIBezierPath bezierPath];[bezierPath moveToPoint:CGPointMake(100, 0)];[bezierPath addLineToPoint:CGPointMake(200, 0)];[bezierPath addLineToPoint:CGPointMake(300, 100)];[bezierPath addLineToPoint:CGPointMake(150, 200)];[bezierPath addLineToPoint:CGPointMake(0, 100)];[bezierPath closePath];
}

贝塞尔曲线的点线使用

  • 对应点ABCDE,使用closePath,形成闭合图形。
    在这里插入图片描述
    ** path的图是向上的,实际展示是向下翻转的。
    path展示效果

添加弧线

  • UIBezierPath类提供了使用弧段初始化新路径对象的支持。bezierPathWithArcCenter:radius:startAngle:endAngle:顺时针:方法的参数定义了包含所需圆弧的圆以及圆弧本身的起点和终点。
#define   DEGREES_TO_RADIANS(degrees)  ((pi * degrees)/ 180)
- (UIBezierPath *)createArcPath
{UIBezierPath *aPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150)radius:75startAngle:0endAngle:DEGREES_TO_RADIANS(135)clockwise:YES];return aPath;
}
//弧是顺时针方向形成的。(逆时针方向画圆弧的虚线部分)

官网图片

添加曲线

  • UIBezierPath类支持在路径中添加Quadratic curveCubic curve Bézier。曲线段从当前点开始,到指定的点结束。曲线的形状使用起点和终点与一个或多个控制点之间的切线定义。添加曲线:

  • Quadratic curve :addQuadCurveToPoint:controlPoint:

  • Cubic curve :addCurveToPoint:controlPoint1:controlPoint2:

  • 因为曲线依赖于路径的当前点,所以必须在调用上述方法之前设置当前点。完成曲线后,当前点将更新为您指定的新终点。
    官网图片 控制点

创建椭圆和矩形路径

椭圆和矩形是使用曲线和线段组合构建的常见路径类型。UIBezierPath类包括bezierPathWithRect:bezierPathWithOvalInRect:用于创建椭圆形或矩形路径的方便方法。这两个方法都创建一个新的路径对象,并用指定的形状初始化它。您可以立即使用返回的path对象,也可以根据需要向其添加更多形状。

如果你想添加一个矩形到一个现有的路径对象中,你必须使用moveToPoint:addLineToPoint:,和closePath方法,就像你对任何其他多边形一样。在矩形的最后一侧使用closePath方法可以方便地添加路径的最后一行,并标记矩形子路径的结束。

如果你想添加一个椭圆到一个现有的路径,最简单的方法是使用核心图形。虽然您可以使用addQuadCurveToPoint:controlPoint:来近似椭圆曲面,但CGPathAddEllipseInRect函数使用起来更简单,也更准确。有关详细信息,请参见核心图形函数修改路径

使用核心图形函数修改路径

  • UIBezierPath类实际上只是CGPathRef数据类型和与该路径相关的绘图属性的包装器。虽然您通常使用UIBezierPath类的方法添加直线段和曲线段,但该类还公开了一个CGPath属性,您可以使用该属性直接修改底层路径数据类型。当您希望使用核心图形框架的功能构建路径时,可以使用此属性。

  • 有两种方法来修改与UIBezierPath对象相关的路径。你可以完全使用Core Graphics函数来修改路径,或者你可以混合使用Core Graphics函数和UIBezierPath方法。在某些方面,完全使用Core Graphics调用修改路径更容易。您可以创建一个可变的CGPathRef数据类型,并调用您需要修改其路径信息的任何函数。完成后,将path对象分配给相应的UIBezierPath对象.

// Create the path data.
CGMutablePathRef cgPath = CGPathCreateMutable();
CGPathAddEllipseInRect(cgPath, NULL, CGRectMake(0, 0, 300, 300));
CGPathAddEllipseInRect(cgPath, NULL, CGRectMake(50, 50, 200, 200));// Now create the UIBezierPath object.
UIBezierPath *aPath = [UIBezierPath bezierPath];
aPath.CGPath = cgPath;
aPath.usesEvenOddFillRule = YES;// After assigning it to the UIBezierPath object, you can release
// your CGPathRef data type safely.
CGPathRelease(cgPath);
  • 如果你选择混合使用Core Graphics函数和UIBezierPath方法,你必须小心地在两者之间来回移动路径信息。因为UIBezierPath对象拥有其底层CGPathRef数据类型,所以不能简单地检索该类型并直接修改它。相反,您必须创建一个可变副本,修改副本,然后将副本赋值给CGPath属性.
UIBezierPath *aPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 300, 300)];// Get the CGPathRef and create a mutable version.
CGPathRef cgPath = aPath.CGPath;
CGMutablePathRef  mutablePath = CGPathCreateMutableCopy(cgPath);// Modify the path and assign it back to the UIBezierPath object.
CGPathAddEllipseInRect(mutablePath, NULL, CGRectMake(50, 50, 200, 200));
aPath.CGPath = mutablePath;// Release both the mutable copy of the path.
CGPathRelease(mutablePath);

渲染Bézier Path路径

  • 创建UIBezierPath对象后,你可以使用它的描边填充方法在当前图形上下文中渲染它。不过,在你调用这些方法之前,通常还有一些其他任务要执行,以确保你的路径被正确绘制:

      1. 使用UIColor类的方法设置所需的笔画填充颜色。
      1. 将形状放置在目标视图中您想要的位置。

      如果您创建了相对于点(0,0)的路径,则可以对当前绘图上下文应用适当的仿射转换。例如,要从点(10,10)开始绘制形状,您将调用CGContextTranslateCTM函数,并为水平和垂直平移值指定10。调整图形上下文(而不是路径对象中的点)是首选,因为通过保存和恢复以前的图形状态,可以更容易地撤消更改。

      1. 更新路径对象的绘图属性。UIBezierPath实例的绘图属性在呈现路径时覆盖与图形上下文相关的值。
- (void)drawRect:(CGRect)rect
{// Create an oval shape to draw.UIBezierPath *aPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 100)];// Set the render colors.[[UIColor blackColor] setStroke];[[UIColor redColor] setFill];CGContextRef aRef = UIGraphicsGetCurrentContext();// If you have content to draw after the shape,// save the current state before changing the transform.//CGContextSaveGState(aRef);// Adjust the view's origin temporarily. The oval is// now drawn relative to the new origin point.CGContextTranslateCTM(aRef, 50, 50);// Adjust the drawing options as needed.aPath.lineWidth = 5;// Fill the path before stroking it so that the fill// color does not obscure the stroked line.[aPath fill];[aPath stroke];// Restore the graphics state before drawing any other content.//CGContextRestoreGState(aRef);
}

如上显示了一个drawRect:方法的示例实现,该方法在自定义视图中绘制一个椭圆形。椭圆边界矩形的左上角位于视图坐标系中的点(50,50)。因为填充操作直接绘制到路径边界,所以此方法在描边之前填充路径。这可以防止填充颜色遮住一半的描边线。
填充与描边

在路径上进行命中检测

  • 要确定一个触摸事件是否发生在路径的填充部分,你可以使用UIBezierPathcontainsPoint:方法。此方法针对路径对象中的所有封闭子路径测试指定点,如果它位于其中任何子路径上或其中任何子路径内,则返回YES

containsPoint:方法和Core Graphics命中测试函数仅在封闭路径上操作。对于打开的子路径,这些方法总是返回NO。如果要对打开的子路径进行命中检测,必须创建路径对象的副本,并在测试点之前关闭打开的子路径。

  • 如果你想在路径的描边部分(而不是填充区域)进行命中测试,你必须使用Core GraphicsCGContextPathContainsPoint函数允许您测试当前分配给图形上下文的路径的填充部分或描边部分上的点。
- (BOOL)containsPoint:(CGPoint)point onPath:(UIBezierPath *)path inFillArea:(BOOL)inFill
{CGContextRef context = UIGraphicsGetCurrentContext();CGPathRef cgPath = path.CGPath;BOOL    isHit = NO;// Determine the drawing mode to use. Default to// detecting hits on the stroked portion of the path.CGPathDrawingMode mode = kCGPathStroke;if (inFill){// Look for hits in the fill area of the path instead.if (path.usesEvenOddFillRule)mode = kCGPathEOFill;elsemode = kCGPathFill;}// Save the graphics state so that the path can be// removed later.CGContextSaveGState(context);CGContextAddPath(context, cgPath);// Do the hit detection.isHit = CGContextPathContainsPoint(context, point, mode);CGContextRestoreGState(context);return isHit;
}
  • 如上显示了一个测试指定点是否与指定路径相交的方法。inFill参数允许调用者指定是否应该根据路径的填充部分或描边部分测试该点。调用方传入的路径必须包含一个或多个封闭子路径,以便命中检测成功。

使用测试

绘制了个类似气泡的玩意
代码实现结果参考

- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;

因为addQuadCurveToPoint中是设置的endPoint,所以上图中的弧点8应是 3的位置,弧点9应是起点位置


- (void)drawRect:(CGRect)rect
{UIBezierPath *aPath = [UIBezierPath bezierPath];[aPath moveToPoint:CGPointMake(50, 50)]; //起点[aPath addLineToPoint:CGPointMake(150, 50)]; //2 弧线起点[aPath addQuadCurveToPoint:CGPointMake(150, 100) controlPoint:CGPointMake(185, 75)]; //8圆点 10控制点 弧线[aPath addLineToPoint:CGPointMake(100, 100)];//4 尖尖角起点[aPath addLineToPoint:CGPointMake(85, 125)]; //5 尖尖角顶点[aPath addLineToPoint:CGPointMake(70, 100)]; //6 尖尖角终点[aPath addLineToPoint:CGPointMake(50, 100)]; //7 左边圆弧起点[aPath addQuadCurveToPoint:CGPointMake(50, 50) controlPoint:CGPointMake(15, 75)]; // 9圆点 11控制点 圆弧[aPath closePath]; // 闭合图形aPath.lineJoinStyle = kCGLineJoinRound;aPath.lineCapStyle = kCGLineCapRound;[[UIColor yellowColor] setStroke];[[UIColor purpleColor] setFill];CGContextRef aref = UIGraphicsGetCurrentContext();CGContextTranslateCTM(aref, 50, 50);aPath.lineWidth = 1;[aPath fill];[aPath stroke];
}

这篇关于iOS-OC-Bézier Path简介的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/284424

相关文章

解决jupyterLab打开后出现Config option `template_path`not recognized by `ExporterCollapsibleHeadings`问题

《解决jupyterLab打开后出现Configoption`template_path`notrecognizedby`ExporterCollapsibleHeadings`问题》在Ju... 目录jupyterLab打开后出现“templandroidate_path”相关问题这是 tensorflo

解读静态资源访问static-locations和static-path-pattern

《解读静态资源访问static-locations和static-path-pattern》本文主要介绍了SpringBoot中静态资源的配置和访问方式,包括静态资源的默认前缀、默认地址、目录结构、访... 目录静态资源访问static-locations和static-path-pattern静态资源配置

Golang的CSP模型简介(最新推荐)

《Golang的CSP模型简介(最新推荐)》Golang采用了CSP(CommunicatingSequentialProcesses,通信顺序进程)并发模型,通过goroutine和channe... 目录前言一、介绍1. 什么是 CSP 模型2. Goroutine3. Channel4. Channe

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

python中os.stat().st_size、os.path.getsize()获取文件大小

《python中os.stat().st_size、os.path.getsize()获取文件大小》本文介绍了使用os.stat()和os.path.getsize()函数获取文件大小,文中通过示例代... 目录一、os.stat().st_size二、os.path.getsize()三、函数封装一、os

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

业务协同平台--简介

一、使用场景         1.多个系统统一在业务协同平台定义协同策略,由业务协同平台代替人工完成一系列的单据录入         2.同时业务协同平台将执行任务推送给pda、pad等执行终端,通知各人员、设备进行作业执行         3.作业过程中,可设置完成时间预警、作业节点通知,时刻了解作业进程         4.做完再给你做过程分析,给出优化建议         就问你这一套下

容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么? K8s的架构原理  控制平面(Control plane)         kube-apiserver         etcd         kube-scheduler         kube-controller-manager         cloud-controlle

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序