我有两个点左和右通过向Y添加一些静态值而X是左右AVG我创建了第3个点 center < / strong>
之后我使用bezier路径绘制曲线并且一切正常。
在上面的曲线中
现在我想再创建两个点(5点曲线)。
一个在中心和左之间,一个在中心和右之间。
我尝试再次拍摄平均值并使用
绘制5点曲线 func drawFivePoint(_ startPoint: CGPoint?, leftCenterPoint: CGPoint?, toControlPoint controlPoint: CGPoint?, toRightControlPoint rightPoint: CGPoint?, toEnd endPoint: CGPoint?) {
var arrPoints = [NSValue]()
if startPoint != nil {
arrPoints.append(NSValue(cgPoint: startPoint!))
}
if leftCenterPoint != nil && !(__CGPointEqualToPoint(leftCenterPoint!, .zero)) {
arrPoints.append(NSValue(cgPoint: leftCenterPoint!))
}
if controlPoint != nil {
arrPoints.append(NSValue(cgPoint: controlPoint!))
}
if rightPoint != nil && !(__CGPointEqualToPoint(rightPoint!, .zero)) {
arrPoints.append(NSValue(cgPoint: rightPoint!))
}
if endPoint != nil {
arrPoints.append(NSValue(cgPoint: endPoint!))
}
guard let bezierPath = UIBezierPath.interpolateCGPoints(withHermite: arrPoints, closed: false) else {
print("path is nil")
return
}
curveSize = bezierPath.bounds
let strokeColor = UIColor.white
if curveLayer != nil {
curveLayer?.removeFromSuperlayer()
curveLayer = nil
}
curveLayer = CAShapeLayer()
curveLayer?.lineWidth = 1.0 / self.zoomScale
curveLayer?.fillColor = UIColor.clear.cgColor
curveLayer?.path = bezierPath.cgPath
curveLayer?.strokeColor = strokeColor.cgColor
viewBase.layer.addSublayer(curveLayer!)
}
错误的结果
问题:如何计算点以使形状不受影响我在曲线上得到5分
答案 0 :(得分:0)
很难说,你想要实现什么,但如果你的目标是找到你在第一步中定义的贝塞尔曲线的一部分,那么看看如何首先定义贝塞尔曲线。 Wikipedia。通常,只有贝塞尔曲线的第一个和最后一个控制点也是曲线的一部分。
要找到特定t(0..1)的贝塞尔曲线上的点P(t),您可以使用De Casteljau's Algorithm
在游乐场试试这个简单的片段。我选择控制点,因此x线性地依赖于Bezier t参数。 y的形状与贝塞尔曲线具有相同的形状,很容易将其视为游乐场中的数值图表
//: Playground - noun: a place where people can play
// point
struct Point {
var x: Double
var y: Double
}
// linear bezier
func linearBezier(p1: Point, p2: Point, t: Double)->Point {
let px = p1.x + t*(p2.x - p1.x)
let py = p1.y + t*(p2.y - p1.y)
return Point(x: px, y: py)
}
// quadratic bezier
func quadraticBezier(p1: Point, p2: Point, p3: Point, t: Double)->Point {
let p12 = linearBezier(p1: p1, p2: p2, t: t)
let p23 = linearBezier(p1: p2, p2: p3, t: t)
return linearBezier(p1: p12, p2: p23, t: t)
}
// cubic bezier
func cubicBezier(p1: Point, p2: Point, p3: Point, p4: Point, t: Double)->Point {
let p12 = linearBezier(p1: p1, p2: p2, t: t)
let p23 = linearBezier(p1: p2, p2: p3, t: t)
let p34 = linearBezier(p1: p3, p2: p4, t: t)
return quadraticBezier(p1: p12, p2: p23, p3: p34, t: t)
}
let p1 = Point(x: 0.0, y: 0.0)
let p2 = Point(x: 15.0, y: 10.0)
let p3 = Point(x: 30.0, y: 5.0)
for t in stride(from: 0.0, through: 1.0, by: 0.025) {
let p = quadraticBezier(p1: p1, p2: p2, p3: p3, t: t)
print(p.x, p.y)
p.x
p.y // see the values as a graph
}
let p4 = Point(x: 45.0, y: 10.0)
for t in stride(from: 0.0, through: 1.0, by: 0.025) {
let p = cubicBezier(p1: p1, p2: p2, p3: p3, p4: p4, t: t)
print(p.x, p.y)
p.x
p.y // see the values as a graph
}
可以进一步做到更通用
func bezier(controlPoints: [Point], t: Double)->[Point] {
if controlPoints.count == 1 { return controlPoints }
var reducedPoints: [Point] = []
for i in 0..<(controlPoints.count - 1) {
let p = linearBezier(p1: controlPoints[i], p2: controlPoints[i+1], t: t)
reducedPoints.append(p)
}
return bezier(controlPoints: reducedPoints, t: t)
}
let points = [p1,p2,p3,p4]
for t in stride(from: 0.0, through: 1.0, by: 0.0125) {
let p = bezier(controlPoints: points, t: t)
p.count // it is alway 1 :-)
p[0].x
p[0].y
}
给你相同的结果。函数bezier
可用于“任意”数量的控制点。接受该帐户,bezier函数仅对定义中的区间(0 ... 1.0)中的t有效,即使您可以计算任何区间中的值。