SwiftUI中基于GeometryReader的椭圆焦点对齐偏移问题
解决SwiftUI中椭圆围绕焦点连线偏移的问题
问题根源
椭圆偏移的核心原因是坐标系变换顺序错误。当前代码先创建以原点为中心的椭圆路径,通过frame设置尺寸后再旋转,最后用position定位。但frame会将视图的原点设为左上角,导致椭圆的几何中心与视图布局中心错位,旋转后出现偏移。
修复方案
使用transformEffect直接对路径进行坐标变换,先平移到焦点连线的中点,再旋转,避免frame和position组合带来的坐标系混乱。
修改椭圆绘制部分的代码:
// Compute Ellipse Properties let centerX = (s_x + d_x) / 2 + geometry.size.width / 2 let centerY = (s_y + d_y) / 2 + geometry.size.height / 2 let focalDistance = C(x: s_x, y: s_y, a: d_x, b: d_y) let semiMajor = F() / 2 let semiMinor = sqrt(pow(semiMajor, 2) - pow(focalDistance / 2, 2)) // Adjust angle for flipped Y-axis (SwiftUI Y-axis points downward) let angle = atan2(s_y - d_y, s_x - d_x) // Draw the ellipse correctly centered on the foci midpoint Path { path in // Create ellipse centered at (0,0) in local coordinates let rect = CGRect(x: -semiMajor, y: -semiMinor, width: semiMajor * 2, height: semiMinor * 2) path.addEllipse(in: rect) } .stroke(Color.red, lineWidth: 2) // First translate to the center point, then apply rotation .transformEffect( CGAffineTransform(translationX: centerX, y: centerY) .rotated(by: angle) )
额外说明
- 原代码中
ellipseAxes()函数内的半短轴计算错误(semiMinor = semiMajor - distanceBetweenFoci / 2不符合椭圆几何公式),但你在body里已经使用了正确的公式semiMinor = sqrt(pow(semiMajor, 2) - pow(focalDistance / 2, 2)),所以可以保留body中的计算逻辑。 - SwiftUI的Y轴是向下的,
atan2(s_y - d_y, s_x - d_x)的角度计算是正确的,无需调整。
内容的提问来源于stack exchange,提问作者BJB
相关产品推荐
相关产品推荐

