我想驱动一条平滑的曲线,使曲线的1/3向外侧2/3向内。这是我想要实现的。
到目前为止,我尝试通过添加1条曲线来进行此操作:
var height: CGFloat = UIScreen.main.bounds.height / 14
let centerWidth = self.frame.width / 2
let screenView = UIScreen.main.bounds
let width = (screenView.width - (2*screenView.width/40)) / 10
path.move(to: CGPoint(x: 0, y: 0)) // start top left
path.addLine(to: CGPoint(x: (centerWidth - width * 2.5), y: 0)) // the beginning of the trough
// first curve down
path.addCurve(to: CGPoint(x: centerWidth , y: height),
controlPoint1: CGPoint(x: (centerWidth - width * 1.33), y: 0), controlPoint2: CGPoint(x: centerWidth - width * 1.33 , y: height))
但是当我尝试此向外弯曲和向内弯曲时具有相同的高度。所以我更改了它,并尝试添加2条曲线,如:
path.move(to: CGPoint(x: 0, y: 0)) // start top left
path.addLine(to: CGPoint(x: (centerWidth - width * 2.5), y: 0)) // the beginning of the trough
// first curve down
path.addCurve(to: CGPoint(x: centerWidth - width * 1.33 , y: height/3),
controlPoint1: CGPoint(x: (centerWidth - width * 1.33), y: 0), controlPoint2: CGPoint(x: centerWidth - width * 1.33 , y: height/3))
path.addCurve(to: CGPoint(x: centerWidth, y: height),
controlPoint1: CGPoint(x: centerWidth - width * 1.33 , y: height/3), controlPoint2: CGPoint(x: centerWidth - width , y: height ))
[我已经尝试了很多东西,但无法画出我想要的东西。所以,我该如何绘制一条曲线,使端点高度的1/3向外而2/3向内看起来像一块。
我愿意接受各种各样的想法。问候
[当我查看设计师的渲染时,如果将其分成两条单独的贝塞尔曲线,则主要观察结果是顶部⅓曲线与底部as曲线是对称的(相对于自身)。对于对称的贝塞尔曲线,四边贝塞尔曲线更易于处理。
并且要使拐点无缝,您需要确保两个控制点(一个用于拐点上方的方形贝塞尔曲线,另一个用于拐点下方的方形贝塞尔曲线)与拐点共线。例如:
例如,需要一些三角函数才能确定这些控制点的位置
let center = CGPoint(x: view.bounds.midX, y: 200)
let radius: CGFloat = 140
let curveOffsetBottom: CGFloat = 30
let curveOffsetInflection: CGFloat = 50
greenCircularShapeLayer.path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: true).cgPath
let h = radius + curveOffsetBottom + 50
let curveBottom = CGPoint(x: center.x,
y: center.y + radius + curveOffsetBottom)
let y0 = radius + curveOffsetBottom - h * 2 / 3
let t0 = asin(y0 / (radius + curveOffsetInflection))
let x0 = y0 / tan(t0)
let inflectionPoint = CGPoint(x: center.x - x0, y: center.y + y0)
let t1 = atan((curveBottom.x - inflectionPoint.x) / (curveBottom.y - inflectionPoint.y))
let t2 = 2 * (.pi / 2 - t1)
let x2 = (curveBottom.y - inflectionPoint.y) / tan(t2)
let x1 = x2 / 2
let cp1 = CGPoint(x: inflectionPoint.x - x1, y: curveBottom.y - h)
let cp2 = CGPoint(x: inflectionPoint.x + x2, y: curveBottom.y)
let curveTop = CGPoint(x: cp1.x - cp1.distance(to: inflectionPoint), y: curveBottom.y - h)
let path = UIBezierPath()
path.move(to: curveTop)
path.addQuadCurve(to: inflectionPoint, controlPoint: cp1)
path.addQuadCurve(to: curveBottom, controlPoint: cp2)
path.addLine(to: CGPoint(x: view.bounds.maxX, y: path.currentPoint.y))
path.addLine(to: CGPoint(x: view.bounds.maxX, y: view.bounds.maxY))
path.addLine(to: CGPoint(x: view.bounds.minX, y: view.bounds.maxY))
path.addLine(to: CGPoint(x: view.bounds.minX, y: curveTop.y))
path.close()
blackCurveShapeLayer.path = path.cgPath
哪里
extension CGPoint {
func distance(to point: CGPoint) -> CGFloat {
hypot(point.x - x, point.y - y)
}
}