椭圆的 SwiftUI 实现:第一定义与第二定义
时间: 2025-07-05 15:45:00
# 椭圆的 SwiftUI 实现:第一定义与第二定义
1. 椭圆的数学定义
第一定义(几何定义)
平面上到两个定点(焦点)的距离之和等于定长(2a)的点的轨迹。
数学表达式:
|PF₁| + |PF₂| = 2a
,其中 a > c
,c
是焦距
第二定义(准线定义)
平面上到定点(焦点)的距离与到定直线(准线)的距离之比为常数 e
(离心率,0 < e < 1
)的点的轨迹。
数学表达式:
|PF| / d = e
,其中 d
是点到准线的距离
2. SwiftUI 实现
椭圆视图(基于第一定义)
struct EllipseFirstDefinitionView: View { let a: CGFloat = 150 // 半长轴 let b: CGFloat = 100 // 半短轴 var c: CGFloat { sqrt(a*a - b*b) } // 焦距 @State private var angle: CGFloat = 0 private let timer = Timer.publish(every: 0.02, on: .main, in: .common).autoconnect() var body: some View { GeometryReader { geometry in let center = CGPoint(x: geometry.size.width/2, y: geometry.size.height/2) ZStack { // 椭圆轨道 Path { path in path.addEllipse(in: CGRect( x: center.x - a, y: center.y - b, width: a * 2, height: b * 2 )) } .stroke(Color.blue, lineWidth: 2) // 两个焦点 Circle() .fill(Color.red) .frame(width: 20) .position(x: center.x - c, y: center.y) Circle() .fill(Color.red) .frame(width: 20) .position(x: center.x + c, y: center.y) // 动态点 let point = CGPoint( x: center.x + a * cos(angle), y: center.y + b * sin(angle) ) Circle() .fill(Color.green) .frame(width: 15) .position(point) // 连接线 Path { path in path.move(to: CGPoint(x: center.x - c, y: center.y)) path.addLine(to: point) path.move(to: CGPoint(x: center.x + c, y: center.y)) path.addLine(to: point) } .stroke(Color.gray.opacity(0.5), lineWidth: 1) } } .frame(height: 300) .onReceive(timer) { _ in angle += 0.02 if angle > 2 * .pi { angle = 0 } } } }
椭圆视图(基于第二定义)
struct EllipseSecondDefinitionView: View { let a: CGFloat = 150 // 半长轴 let b: CGFloat = 100 // 半短轴 var c: CGFloat { sqrt(a*a - b*b) } // 焦距 var e: CGFloat { c/a } // 离心率 var directrixX: CGFloat { a/e } // 准线位置 @State private var angle: CGFloat = 0 private let timer = Timer.publish(every: 0.02, on: .main, in: .common).autoconnect() var body: some View { GeometryReader { geometry in let center = CGPoint(x: geometry.size.width/2, y: geometry.size.height/2) ZStack { // 椭圆轨道 Path { path in path.addEllipse(in: CGRect( x: center.x - a, y: center.y - b, width: a * 2, height: b * 2 )) } .stroke(Color.blue, lineWidth: 2) // 焦点 Circle() .fill(Color.red) .frame(width: 20) .position(x: center.x - c, y: center.y) // 准线 Path { path in path.move(to: CGPoint(x: center.x + directrixX, y: center.y - b * 1.5)) path.addLine(to: CGPoint(x: center.x + directrixX, y: center.y + b * 1.5)) } .stroke(Color.orange, lineWidth: 2) // 动态点 let point = CGPoint( x: center.x + a * cos(angle), y: center.y + b * sin(angle) ) Circle() .fill(Color.green) .frame(width: 15) .position(point) // 连接线和垂线 Path { path in // 焦点到点的距离 path.move(to: CGPoint(x: center.x - c, y: center.y)) path.addLine(to: point) // 点到准线的距离 path.move(to: point) path.addLine(to: CGPoint(x: center.x + directrixX, y: point.y)) } .stroke(Color.gray.opacity(0.5), lineWidth: 1) } } .frame(height: 300) .onReceive(timer) { _ in angle += 0.02 if angle > 2 * .pi { angle = 0 } } } }
3. 预览视图
struct EllipseDefinitionsPreview: View { var body: some View { VStack(spacing: 30) { VStack { Text("椭圆第一定义") .font(.title) Text("到两定点距离之和为定值") .font(.subheadline) EllipseFirstDefinitionView() } VStack { Text("椭圆第二定义") .font(.title) Text("到定点距离与到定直线距离比为定值") .font(.subheadline) EllipseSecondDefinitionView() } } .padding() } }
struct EllipseDefinitionsPreview_Previews: PreviewProvider { static var previews: some View { EllipseDefinitionsPreview() } }
4. 实现特点
1. 精确数学计算:
- 使用标准椭圆参数方程 (a*cosθ, b*sinθ)
- 正确计算焦距 c = √(a² - b²)
- 第二定义中准确计算准线位置 x = a/e
2. 动态可视化:
- 绿色点沿椭圆轨迹运动
- 第一定义显示到两个焦点的距离
- 第二定义显示到焦点和准线的距离
3. 专业标注:
- 红色点表示焦点
- 橙色线表示准线
- 灰色辅助线帮助理解定义
4. 响应式布局:
- 使用 GeometryReader
确保在不同设备上正确居中
- 所有计算基于视图中心坐标
这个实现完整展示了椭圆的两种定义方式,并通过动画直观演示了它们的几何特性。