CAShapeLayer + BezierPath 处理图形编辑

我们做图形编辑的时候,做了一个ShapeOperator类来操作图形,里面存储了图形的尺寸位置、旋转角度等信息,可以生成贝塞尔曲线,将其赋值给 CAShapeLayer即可完成渲染

旋转

SO上找到了操作贝塞尔曲线旋转的最佳实践:https://stackoverflow.com/questions/13738364/rotate-cgpath-without-changing-its-position

  • 针对某个旋转,先以图形中心点的负值做移动,将中心点移动到“视图”左上角,再做旋转,然后再移动回来。
  • 上面涉及三次 transform, 通过 transformConcat连接,计算出最终 transfrom,赋值给贝塞尔曲线的 transform 属性

平移

直接改变控制点即可

编辑控制点

以矩形为例,矩形有四个控制点,即几个角,如果没有旋转,拖动任意控制点就能改变图形的大小,也很直观,但是增加了旋转以后,复杂度陡然提升

矩形的表示
  • 起始点 (x, y)
  • 宽度 width
  • 高度 height
  • 旋转角度 rotation
控制点转换
  • 如果没有旋转的图形,改变的控制点,很容易对应出起始点和宽高的改变,比如移动矩形左上角,就是把起始点变成拖动后的点,对应增加宽高
  • 如果我们在一个旋转了一定角度的图形上,拖动控制点,我们需要知道这个控制点到底如何影响上面的尺寸位置的,拖动后的点的坐标,是未旋转的控制点位置,追加了旋转角度后的坐标
  • 所以第一步是去除旋转的影响,iOS 为我们提供了 CGPoint 的 transform 变换的计算方法 CGPointApplyAffineTransform
  • 上面旋转章节提到,做旋转需要三次 transform,把它 concat 后的最终 transfrom 做 CGAffineTransformInvert,再应用给新的控制点,就得到了矩形未旋转时的新控制点位置,这就很容易把对应的起始点和宽高计算出来了,然后再把图形旋转到对应角度。
  • 但是旋转以后,和以前的图形就不对齐了,这是个大坑,什么叫对齐?下面详细说
有旋转的控制点变换追加平移
  1. 我们插入了下面的图形,边长 a,图形中心点 (x, y)
  1. 然后旋转这个图形到下图,
  1. 接着拖动图形最下面的这个顶点,让图形变大成边长b,我们期望的是下图的效果

想达到上面的效果,我们有两种途径:

  • 旋转中心点不变,仅改变边长尺寸,这样我们在做图形旋转的时候,先对图形进行(-x, -y)的移动,然后旋转,再进行 (x, y) 的移动,就能满足上图的效果(仅最底下的控制点变化了,其它边以及顶部控制点与原先重合)。但是这样有一个问题,下次旋转的时候,就不是沿着图形中心点旋转了,不过这个思路能帮我们找到正确答案
  • 始终保持图形中心点旋转。但是,因为编辑后,边长从 a 变成 b ,图形中心点会变成 (x', y'),那旋转以后,图形的顶点和其它边就没法与原先重合,而是像下图

如果想达成期望的效果,在编辑图形的时候,还要对图形进行平移,这样旋转以后就能使顶部的点与原先重合

我们按途径1,以不变旋转中心点的方式旋转以后,图形的中心点变成了 (x", y"),可以从下图看到,(x", y") 与 (x', y') 存在平移,而此平移的变化由来,就是以 (x, y) 为中心,将(x', y')旋转图形所旋转的角度,变到了(x", y") ,移动量就是 (x" - x', y" - y')

这样,在编辑的时候,计算编辑前后的中心点变化,并应用上面的变换,得到图形需要平移的量,追加给图形,就可以达到预期的效果了

总结

图形编辑,有时候看起来很简单直观的事情,在实际代码上,就会非常困难,最近在做曲线的旋转,又是一个大坑,因为曲线的起始点,终点、控制点三个点,位置的不同,决定了曲线的形状,拖动终点或起点的时候,三个点都会变化,而且一会正一会负,需要根据象限分别判断曲线是凸的还是凹的,头大啊。。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容