椭圆的 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 确保在不同设备上正确居中
- 所有计算基于视图中心坐标
这个实现完整展示了椭圆的两种定义方式,并通过动画直观演示了它们的几何特性。
