我有两行带有SwiftUI路径的代码(见下图).我想把它们连接成一个完美光滑的弧线,这样它看起来就像this图像中的演讲气泡 tail .

我正在努力让它顺利地连接起来.正如你在我的图像中看到的,它几乎是完美的,但直线和弧线(在右边)之间的第一个连接并不完美.

你知道我做错了什么吗?我甚至把它画在纸上,我看不出哪个值是不正确的.

enter image description here

struct SpeechBubbleTail: Shape {
    private let radius: CGFloat
    init(radius: CGFloat = 10) {
        self.radius = radius
    }

    func path(in rect: CGRect) -> Path {
        Path { path in
            path.move(to: CGPoint(x: rect.maxX, y: rect.minY))
            path.addLine(to: CGPoint(x: rect.minX + radius, y: rect.maxY - radius))
            
            path.addArc(
                center: CGPoint(x: rect.minX + ((radius / 2) * 1.5), y: rect.maxY - (radius * 1.5)),
                            radius: (radius / 2),
                            startAngle: Angle(degrees: 45),
                            endAngle: Angle(degrees: 180),
                            clockwise: false
                        )
                        
            path.addLine(to: CGPoint(x: rect.minX + ((radius / 2) * 0.5), y: rect.minY))
        }
    }
}

推荐答案

让我们将radius重命名为diameter,因为您使用radius / 2作为半径...

所以你有两条线,你想用圆弧连接起来.

  • (x: rect.maxX, y: rect.minY)(x: rect.minX + diameter, y: rect.maxY - diameter)的对角线,以及,
  • X=rect.minX + diameter / 4处的垂直线

观测:cannot be度圆的中心在(x: rect.minX + ((diameter / 2) * 1.5), y: rect.maxY - (diameter * 1.5)度.

Desmos上的演示

enter image description here

突出显示的点是对角线的终点.圆圈根本不会穿过它.


不过,不用担心,有一个方便的addArc(tangent1End:tangent2End:radius:transform:)API,它取两条直线和一个半径,并产生一个与这两条直线相切的圆!

path.move(to: CGPoint(x: rect.maxX, y: rect.minY))
path.addLine(to: CGPoint(x: rect.minX + diameter, y: rect.maxY - diameter))
path.addArc(
    // tangent1End is the intersection of the two lines when you extend them
    tangent1End: CGPoint(x: rect.minX + diameter / 4, y: rect.maxY - diameter / 4),
    tangent2End: CGPoint(x: rect.minX + ((diameter / 2) * 0.5), y: rect.minY),
    radius: diameter / 2)
path.addLine(to: CGPoint(x: rect.minX + ((diameter / 2) * 0.5), y: rect.minY))

这个post有一个非常漂亮的数字,显示了这种超载是如何工作的.

另请参见Math.SE上的this post,以了解背后的数学原理.

Swift相关问答推荐

如何使用Swift宏向 struct 体及其init函数添加新成员?

如何分解阿拉伯字母?

如何在SWIFT中轻松格式化公制和英制使用的UnitVolume

NSWindow中以编程方式创建的TextField快捷方式与SwiftUI

如何让ScrollView缩小到合适的大小,并在没有黑客攻击的情况下占用最小空间

在Xcode SWIFT中运行用Ionic编写的函数

如何避免切换视图递归onChange调用SwiftUI

如何在应用程序区域永久更改 NSCursor?

如何为我的项目设置生命周期选项?

如何判断设备是否为 Vision Pro - Xcode 15 Beta 4

减小SF符号的边框宽度

如何删除快速处理消息

@Binding 在@StateObject 和 View 上被发布了两次?

NavigationStack 和 TabView - 工具栏和标题不显示

在 struct 中的序列和非序列泛型函数之间进行 Select

如何在 Swift 中使用子定义覆盖父类扩展

如何在 SwiftUI 中将图像传递到 2 个视图

引用类型(类)不需要但 struct 需要的可识别 id

Swift 2 或 3 中的 Google Analytics 问题

无法使用锚激活约束