可可 – 使用8个三次贝塞尔曲线创建(近似)圆的控制点

可可 – 使用8个三次贝塞尔曲线创建(近似)圆的控制点,第1张

概述前提 我有一个圆圈,动画成8个贝塞尔曲线的形状.为了使过渡平滑,我需要用8个立方贝塞尔曲线制作圆. 这是我到目前为止所拥有的: 代码 - (UIBezierPath*)pathBubbleLeft { UIBezierPath *path = [UIBezierPath new]; [path moveToPoint:p(sqlx, sqlMidy)]; CGFloat 前提

我有一个圆圈,动画成8个贝塞尔曲线的形状.为了使过渡平滑,我需要用8个立方贝塞尔曲线制作圆.
这是我到目前为止所拥有的:

代码

- (UIBezIErPath*)pathBubbleleft {    UIBezIErPath *path = [UIBezIErPath new];    [path movetoPoint:p(sqlx,sqlMIDy)];    CGfloat r = sqlW/2;    CGfloat sin45 = 0.7071 * r;    CGfloat cos45 = 0.7071 * r;    [path addrelativeCurvetoPoint:point(sqlMIDx - cos45,sqlMIDy - sin45) control1:vector(0,0.4) control2:vector(0.5,0.8)];    [path addrelativeCurvetoPoint:point(sqlMIDx,sqly) control1:vector(0.2,0.5) control2:vector(0.4,1)];    [path addrelativeCurvetoPoint:point(sqlMIDx + cos45,sqlMIDy - sin45) control1:vector(0.6,0) control2:vector(0.8,0.5)];    [path addrelativeCurvetoPoint:point(sqlMaxx,sqlMIDy) control1:vector(0.5,0.2) control2:vector(1,0.5)];    [path addrelativeCurvetoPoint:point(sqlMIDx + cos45,sqlMIDy + sin45) control1:vector(0,sqlMaxy) control1:vector(0.2,1)];    [path addrelativeCurvetoPoint:point(sqlMIDx - cos45,sqlMIDy + sin45) control1:vector(0.6,0.5)];    [path addrelativeCurvetoPoint:point(sqlx,0.5)];    return path;}

路径从左开始顺时针(从pi到pi / 2,3pi / 4,pi)

点和向量是CGPointMake和CGVectorMake的短路

‘sql’在sqlx,sqly,sqlMIDx,sqlMIDY,sqlMaxx& sqlMaxy代表’squareleft’,即圆的边界矩形.这些都是CGfloats.

addrelativeCurvetoPoint用于相对于起点/终点定义控制点. (0,0)开始,(1,1)结束.更容易阅读.

- (voID)addrelativeCurvetoPoint:(CGPoint)endPoint control1:(CGVector)controlPoint1 control2:(CGVector)controlPoint2 {    CGPoint start = self.currentPoint;    CGPoint end = endPoint;    CGfloat x1 = start.x + controlPoint1.dx*(end.x - start.x);    CGfloat x2 = start.x + controlPoint2.dx*(end.x - start.x);    CGfloat y1 = start.y + controlPoint1.dy*(end.y - start.y);    CGfloat y2 = start.y + controlPoint2.dy*(end.y - start.y);    [self addCurvetoPoint:endPoint controlPoint1:CGPointMake(x1,y1) controlPoint2:CGPointMake(x2,y2)];}

结果到目前为止:

红色圆圈有点波浪状.这就是我想解决的问题.

下面,左侧圆圈使用上面的代码,右侧圆圈由4条曲线组成,顶部插入2个零长度,底部插入2个([path addlinetoPoint:path.currentPoint];).

从左边到花生中间的过渡是好的,但从中间到右边是奇怪的

解决方法 使用四个分段,使用三次贝塞尔曲线的圆近似不能比@fang在评论中给出的0.55228值更圆:它只是数学上唯一的值,其中立方贝塞尔曲线最佳近似圆圈.在无限精度表示中,它实际上是您获得的值:

4        angle       4                     sqrt(2) - 1k =  - * tan(-------)  =  - * tan(pi/8)  =  4 * -----------     3          2         3                          3

并且是0.5522847498307933984022516322796 […].这将为您提供4段最佳近似值,因此如果您需要使用8个段,我们需要一个不同的值,这意味着我们需要使用推导给k我们的角度为pi / 2(四分之一圆),看看它为pi / 4(第八个圆圈)提供了什么.所以:我们将角度pi / 4插入到approximating circles with cubic curves的Primer on Bezier Curve部分中概述的功能中,我们得到:

start = {  x: 1,y: 0}c1 = {  x: 1,y: 4/3 * tan(pi/16)}c2 = {  x: cos(pi/4) + 4/3 * tan(pi/16) * sin(pi/4)  y: sin(pi/4) - 4/3 * tan(pi/16) * cos(pi/4)}e = {  x: cos(pi/4)  y: sin(pi/4)}

这给了我们这些(完全有用的)近似坐标:

s  = (1,0)c1 = (1,0.265216...)c2 = (0.894643...,0.51957...)e  = (0.7071...,0.7071...)

这将是段1,然后其余的段只是通过对称得出,段2是:

s  = (0.7071...,0.7071...)c1 = (0.51957...,0.894643...)c2 = (0.265216...,1)e  = (0,1)

这些坐标的演示覆盖了四分之一圆,这里是:http://jsbin.com/ridedahixu/edit?html,output

其余的是(,– ),( –,)和( –,– )象限中明显的对称性.

这些是最好的近似值,所以:如果bezIErPathWithovalInRect(…)做了别的事情,那么它比我们几十年前制定的值更不正确=)

总结

以上是内存溢出为你收集整理的可可 – 使用8个三次贝塞尔曲线创建(近似)圆的控制点全部内容,希望文章能够帮你解决可可 – 使用8个三次贝塞尔曲线创建(近似)圆的控制点所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1003594.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存