我使用一些传递点创建了虚线UIBezierPath。
PathCreator {
func createPath(resultPoints: [CGPoint]) -> UIBezierPath {
let path = UIBezierPath()
for i in 0..<(resultPoints.count-1) {
if resultPoints[i] is CircleCenterPoint {
continue
}
if resultPoints[i] is ArcEndPoint {
path.move(to: resultPoints[i].cg())
path.addLine(to: resultPoints[i+1].cg())
}
if let arcStartPoint = resultPoints[i] as? ArcStartPoint,
let circleCenterPoint = resultPoints[i+1] as? CircleCenterPoint,
let arcEndPoint = resultPoints[i+2] as? ArcEndPoint {
path.addArc(withCenter: circleCenterPoint.cg(),
radius: circleCenterPoint.radius,
startAngle: arcStartPoint.arcStartAngle,
endAngle: arcEndPoint.arcEndAngle,
clockwise: circleCenterPoint.clockwise)
} else {
path.move(to: resultPoints[i].cg())
path.addLine(to: resultPoints[i+1].cg())
}
}
return path
}
}
我简化了PathCreator,但完全看起来像这样
select rank(window(*)) from StockEvent.win:length(10)
但有时我在子路径的交界处遇到问题:
我缺少什么?
答案 0 :(得分:2)
仅在第一点使用“ path.move”。对于其余几点,请使用“ path.addLine”。
因此解决方案如下:
PathCreator {
func createPath(resultPoints: [CGPoint]) -> UIBezierPath {
var wMoved = false;
let path = UIBezierPath()
for i in 0..<(resultPoints.count-1) {
if resultPoints[i] is CircleCenterPoint {
continue
}
if resultPoints[i] is ArcEndPoint {
if wMoved {
path.addLine(to: resultPoints[i].cg())
} else {
path.move(to: resultPoints[i].cg())
wMoved = true
}
path.addLine(to: resultPoints[i+1].cg())
}
if let arcStartPoint = resultPoints[i] as? ArcStartPoint,
let circleCenterPoint = resultPoints[i+1] as? CircleCenterPoint,
let arcEndPoint = resultPoints[i+2] as? ArcEndPoint {
path.addArc(withCenter: circleCenterPoint.cg(),
radius: circleCenterPoint.radius,
startAngle: arcStartPoint.arcStartAngle,
endAngle: arcEndPoint.arcEndAngle,
clockwise: circleCenterPoint.clockwise)
} else {
if wMoved {
path.addLine(to: resultPoints[i].cg())
} else {
path.move(to: resultPoints[i].cg())
wMoved = true
}
path.addLine(to: resultPoints[i+1].cg())
}
}
return path
}
}
答案 1 :(得分:0)
由于您的CAShapeLayer是单个路径,因此请设置路径的lineJoin属性。在你的情况下,我认为kCALineJoinRound将起作用。 Possible line join values.
pathLayer.lineJoin = kCALineJoinRound
答案 2 :(得分:0)
我很久没有关注这个问题了。但是现在,当我回来时,我发现我实际上在更改代码,并且看起来工作得很好。这是可以发布到操场上并经过测试的代码。同样,此代码不期望任何特殊类型的要点和其他帮助对象。签出:)
import UIKit
import PlaygroundSupport
class PathCreator {
func createPath(by points: [CGPoint]) -> CGPath {
let path = CGMutablePath()
if points.count >= 3 {
path.move(to: points.first!)
for i in 0..<(points.count - 2) {
let startPoint = points[i]
let middlePoint = points[i+1]
let endPoint = points[i+2]
let isOnOneLin = isOnOneLine(point1: startPoint, point2: middlePoint, point3: endPoint)
if isOnOneLin {
path.addLine(to: middlePoint)
if i == points.count - 3 {
path.addLine(to: endPoint)
break
}
} else {
let currentAngleValue = angleBetween(vector1: (startPoint, middlePoint), vector2: (middlePoint, endPoint))
print(currentAngleValue)
if currentAngleValue < 45 {
path.addArc(tangent1End: middlePoint, tangent2End: endPoint, radius: 1)
} else {
path.addArc(tangent1End: middlePoint, tangent2End: endPoint, radius: 10)
}
if i == points.count - 3 {
path.addLine(to: endPoint)
break
}
}
}
} else if points.count == 2 {
path.move(to: points.first!)
path.addLine(to: points[1])
}
return path
}
private func angleBetween(vector1: (CGPoint, CGPoint), vector2: (CGPoint, CGPoint)) -> CGFloat {
// vector1.0
// ^
// \
// \
// \
// \
// ---------->vector2.1
// vector1.1
// vector2.0
let dx1 = vector1.0.x - vector1.1.x
let dy1 = vector1.0.y - vector1.1.y
let vector1 = CGVector(dx: dx1, dy: dy1)
let dx2 = vector2.1.x - vector2.0.x
let dy2 = vector2.1.y - vector2.0.y
let vector2 = CGVector(dx: dx2, dy: dy2)
let scalarProduct = vector1.dx * vector2.dx + vector1.dy * vector2.dy
let vector1Module = sqrt(vector1.dx * vector1.dx + vector1.dy * vector1.dy)
let vector2Module = sqrt(vector2.dx * vector2.dx + vector2.dy * vector2.dy)
let result = acos(scalarProduct / (vector1Module * vector2Module))
return result * 180 / .pi
}
private func isOnOneLine(point1: CGPoint, point2: CGPoint, point3: CGPoint) -> Bool {
let x1 = point1.x
let x2 = point2.x
let x3 = point3.x
let y1 = point1.y
let y2 = point2.y
let y3 = point3.y
let a = (x1 - x3) * (y2 - y3)
let b = (x2 - x3) * (y1 - y3)
let area = 1 / 2 * (a - b)
if area != 0 {
return false
} else {
return true
}
}
}
let str = "hello"
let points = [CGPoint(x: 150, y: 150),
CGPoint(x: 350, y: 150),
CGPoint(x: 350, y: 350),
CGPoint(x: 550, y: 350),
CGPoint(x: 550, y: 450),
CGPoint(x: 205, y: 455),
CGPoint(x: 450, y: 650),
CGPoint(x: 185, y: 750)]
let view = UIView(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000))
view.backgroundColor = .white
PlaygroundPage.current.liveView = view
let pathLayer = CAShapeLayer()
pathLayer.strokeColor = UIColor.blue.cgColor
pathLayer.lineWidth = 4.0
pathLayer.fillColor = UIColor.clear.cgColor
pathLayer.lineDashPattern = [5.0, 2.0]
pathLayer.lineDashPhase = 0
view.layer.addSublayer(pathLayer)
let pathCreator = PathCreator()
let path = pathCreator.createPath(by: points)
pathLayer.path = path
结果在图像上:
尽管解决方案可能并不完美。我认为这对某人可能会有帮助。