
如上图所示,绿色矩形就是我们要绘制圆弧的区域,咖啡色的圆弧就是我们要绘制的效果。
控制点M controPoint是D、C两个点处引出切线的交点
示例代码是swift,但数学公式是共通的,bezier path 是平台无关的
iOS平台A点坐标为(0,0), C点坐标为(width, carve_h), M点y坐标为负数
override func initUI() {
let width = ScreenWidth()
// 蓝色header内,白色圆弧计算path
let curve_h: CGFloat = 20 // curve_view.heght = 20
let controlPoint = getControlPointFrom(bounds: CGRect(x: 0, y: 0, width: width, height: curve_h))
//
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: curve_h))
path.addQuadCurve(to: CGPoint(x: width, y: curve_h), controlPoint: controlPoint)
path.close()
let fillCurve = CAShapeLayer()
fillCurve.frame = CGRect(x: 0, y: 0, width: width, height: curve_h)
fillCurve.path = path.cgPath
fillCurve.fillColor = UIColor.white.cgColor
fillCurve.lineWidth = 0
curve_view.layer.insertSublayer(fillCurve, at: 0)
}
注意:设View的宽为width,高为height,必须满足height <= width/2,才存在通过指定的三点的圆。
// 在View.bounds内绘制一段圆弧,从左下角开始,经过上边中点,到右下角。三点确定一个圆。
func getControlPointFrom(bounds: CGRect) -> CGPoint {
let width = bounds.size.width
let curve_h = bounds.size.height
// 计算curve_view内圆弧的半径(圆弧过3点,(0, curve_h), (width/2, 0), (width, curve_h))
let radius_f = ((curve_h*curve_h) + (width/2)*(width/2))/(2*curve_h)
let cosValue = (width/2)/CGFloat(radius_f) // 余弦值
// 求角度(curve_view底边和半径夹角)
let sista1 = acosf(Float(cosValue))
let sista2 = Float.pi/2 - sista1
let distance = tanf(sista2)*(Float(width/2))
let controlY = curve_h - CGFloat(distance)
return CGPoint(x: width/2, y: controlY)
}
网友评论