You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何求解经验曲线与已知圆心半径的圆的交点?

解决拟合曲线与已知圆的交点问题

我来一步步帮你搞定这个问题,核心思路是先把你的经验数据拟合出可靠的曲线模型,再联立圆的方程求解交点。下面是具体实现步骤:

1. 补全数据并拟合曲线模型

首先先把你的数据补全(假设最后一个y值是0.25,你可以根据实际观测值调整),然后根据数据趋势选择合适的拟合模型。从x递增y递减的趋势来看,我们先尝试幂函数模型(如果拟合效果不好,也可以换成指数模型或多项式模型):

# 输入你的经验数据
x <- c(0.05, 0.20, 0.35, 0.50, 0.65, 0.80, 0.95, 1.10, 1.25, 1.40, 1.55, 1.70, 1.85, 2.00, 2.15, 2.30, 2.45, 2.60, 2.75, 2.90, 3.05)
y <- c(1.52, 1.44, 1.38, 1.31, 1.23, 1.15, 1.06, 0.96, 0.86, 0.76, 0.68, 0.61, 0.54, 0.47, 0.41, 0.36, 0.32, 0.29, 0.27, 0.26, 0.25)

# 用非线性最小二乘法拟合幂函数:y = a * x^b
fit_model <- nls(y ~ a * x^b, start = list(a = 1.5, b = -0.5))
# 查看拟合结果
summary(fit_model)

# 定义拟合后的曲线函数
curve_func <- function(x_val) predict(fit_model, newdata = data.frame(x = x_val))

如果幂函数拟合效果不理想,你可以换成指数模型(y ~ a * exp(b*x))或者三次多项式(lm(y ~ poly(x, 3))),重点是选拟合优度高、符合数据趋势的模型。

2. 联立圆的方程求解交点

假设已知圆的圆心为(h, k),半径为r,圆的方程是:

$(x - h)^2 + (y - k)^2 = r^2$

我们把拟合得到的y = curve_func(x)代入圆的方程,得到关于x的单变量方程,再求解这个方程的根,就是交点的x坐标,对应y值可以代入曲线函数得到。

这里用rootSolve包来求解多根(如果只有一个交点,用基础包的uniroot也可以):

# 安装并加载rootSolve包(首次使用需要安装)
# install.packages("rootSolve")
library(rootSolve)

# 替换成你实际的圆心和半径
circle_center_h <- 1
circle_center_k <- 1
circle_radius <- 1

# 定义要求解的方程:(x-h)² + (curve_func(x)-k)² - r² = 0
target_equation <- function(x_val) {
  (x_val - circle_center_h)^2 + (curve_func(x_val) - circle_center_k)^2 - circle_radius^2
}

# 设置x的求解范围(基于你的数据区间)
x_search_range <- c(min(x), max(x))

# 求解区间内所有根
intersection_x <- uniroot.all(target_equation, interval = x_search_range)

# 计算对应的y值
intersection_y <- curve_func(intersection_x)

# 输出交点结果
intersections <- data.frame(x = intersection_x, y = intersection_y)
print("曲线与圆的交点:")
print(intersections)

3. 可视化验证结果

为了确认交点正确,我们可以把原始数据、拟合曲线、圆和交点画出来:

plot(x, y, pch = 16, main = "拟合曲线与圆的交点", xlab = "x", ylab = "y")
# 绘制拟合曲线
curve(curve_func(x), add = TRUE, col = "blue", lwd = 2)
# 绘制圆
theta_seq <- seq(0, 2*pi, length.out = 100)
circle_x <- circle_center_h + circle_radius*cos(theta_seq)
circle_y <- circle_center_k + circle_radius*sin(theta_seq)
lines(circle_x, circle_y, col = "red", lwd = 2)
# 标记交点
points(intersection_x, intersection_y, pch = 16, col = "green", cex = 1.5)
# 添加图例
legend("topright", 
       legend = c("原始数据", "拟合曲线", "圆", "交点"),
       col = c("black", "blue", "red", "green"),
       lwd = c(NA, 2, 2, NA),
       pch = c(16, NA, NA, 16))

小提示

  • 如果拟合的是多项式模型,联立后的方程是多项式方程,可以用polyroot函数直接求解,效率更高。
  • 若方程在搜索区间内有多个根,uniroot.all能一次性找到所有根,比uniroot更实用。
  • 确保拟合的曲线在搜索区间内连续可导,否则求解可能出现错误。

内容的提问来源于stack exchange,提问作者Mercurial

火山引擎 最新活动