我有一个圆圈,动画成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];).
从左边到花生中间的过渡是好的,但从中间到右边是奇怪的
解决方法
4 angle 4 sqrt(2) - 1 k = - * 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(…)做了别的事情,那么它比我们几十年前制定的值更不正确=)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。