如何在SwiftUI中做出平滑的曲线?

问题描述 投票:0回答:1

enter image description here

嗨,我正在尝试使直线和曲线之间的连接更平滑,这样肉眼就看不见,这是我的代码:

`结构 CustomShape:形状 { func 路径(在矩形中:CGRect)-> 路径 { var 路径 = Path()

    // Set the desired number of segments
    let numberOfSegments = 5

    // Calculate the width of each segment to fit the rect width
    let segmentWidth = rect.width / CGFloat(numberOfSegments - 1)

    // Adjust the start point to be centered
    let startY = rect.midY // Start in the middle of the rect
    path.move(to: CGPoint(x: rect.minX, y: startY))

    // Draw the segments
    for i in 0..<numberOfSegments {
        let xOffset = CGFloat(i) * segmentWidth
        var yPoint = (i % 2 == 0) ? rect.minY : rect.maxY
        
        if i == numberOfSegments - 1 {
            yPoint = rect.midY
        }
        
        let nextPoint = CGPoint(x: rect.minX + xOffset, y: yPoint)
        
        // Add line to the next point
        path.addLine(to: nextPoint)

        // Prepare for curve
        if i < numberOfSegments - 1 {
            let curveControlPointYOffset: CGFloat = 50 // Smaller value for a subtle transition
            let controlPointY = (i % 2 == 0) ? yPoint - curveControlPointYOffset : yPoint + curveControlPointYOffset
            
            // Control point is now adjusted to make the curve start smoothly from the line
            let controlPointX = rect.minX + xOffset + segmentWidth / 2
            let controlPoint = CGPoint(x: controlPointX, y: controlPointY)
            
            // Curve to the right point
            let rightPoint = CGPoint(x: rect.minX + xOffset + segmentWidth, y: yPoint)
            path.addQuadCurve(to: rightPoint, control: controlPoint)
        }
    }

    return path
}`

}

enter image description here

这就是我想要的样子

swiftui path
1个回答
0
投票

您应该绘制circular弧,而不是四边形曲线。圆的两条边与您在此处绘制的垂直线相切,因此如果您仅在 0 到 180 度之间绘制直径为

segmentWidth
的圆弧,它看起来会很平滑。

func path(in rect: CGRect) -> Path {
    var path = Path()
    let numberOfSegments = 5
    
    let segmentWidth = rect.width / CGFloat(numberOfSegments - 1)
    let radius = segmentWidth / 2

    let startY = rect.midY
    path.move(to: CGPoint(x: rect.minX, y: startY))

    // Draw the segments
    for i in 0..<numberOfSegments {
        let xOffset = CGFloat(i) * segmentWidth
        // you should subtract radius from the min/max Ys
        // otherwise you'd be drawing outside the bounds of the rect
        var yPoint = (i % 2 == 0) ? 
                    rect.minY + radius :
                    rect.maxY - radius
        
        if i == numberOfSegments - 1 {
            yPoint = rect.midY
        }
        
        let nextPoint = CGPoint(x: rect.minX + xOffset, y: yPoint)
        path.addLine(to: nextPoint)
        
        if i < numberOfSegments - 1 {
            // closeSubpath, because otherwise addArc would undesirably
            // close the path by joining the end of the arc to the start of the arc
            path.closeSubpath()
            path.addArc(
                center: .init(x: nextPoint.x + radius, y: nextPoint.y),
                radius: radius,
                startAngle: .zero,
                endAngle: .degrees(180),
                clockwise: i % 2 == 0
            )
            // move(to:) the end of the arc, so that a new subpath is created
            path.move(to: .init(x: nextPoint.x + segmentWidth, y: nextPoint.y))
        }
    }
    return path
}
© www.soinside.com 2019 - 2024. All rights reserved.