【问题标题】:how to plot ellipse given a general equation in R?给定R中的一般方程,如何绘制椭圆?
【发布时间】:2025-12-26 15:05:07
【问题描述】:

椭圆一般方程:

a * x ^ 2 + b * y ^ 2 + c * x * y + d * x + e * y + f = 0

【问题讨论】:

  • R中有哪些函数可以绘制椭圆?我对他们的论点很感兴趣。
  • R 中的 Package ellipse 可能对您有所帮助。请通过此链接-cran.r-project.org/web/packages/ellipse/ellipse.pdf
  • 贴上更正:*a和b是半轴*和坐标是(sin(phi)而不是下面第二行的cos(phi)x <- xc + a*cos(t)*cos(phi) - b*sin(t)*sin(phi)y <- yc + a*cos(t)*SIN(phi) + b*sin(t)*cos(phi)
  • 通常的方法是遍历一系列 x 值,计算 y 值,然后让绘图软件在点之间绘制线或样条线。这里唯一的问题是你必须做两次:一次用于椭圆的上曲线,另一次用于下曲线。

标签: r math plot ellipse


【解决方案1】:

你可以使用我的包PlaneGeometry(希望很快在 CRAN 上):

library(PlaneGeometry)

ell <- EllipseFromEquation(A = 4, B = 2, C = 3, D = -2, E = 7, F = 1)
box <- ell$boundingbox()
plot(NULL, asp = 1, xlim = box$x, ylim = box$y, xlab = NA, ylab = NA)
draw(ell, col = "yellow", border = "blue", lwd = 2)

【讨论】:

    【解决方案2】:

    我们可以从ellipseparametric方程开始(以下来自*),我们需要5个参数:中心(xc, yc)(h,k)另一种表示法,轴长度a, b和x 轴与主轴phitau 之间的角度以另一种表示法表示。

    xc <- 1 # center x_c or h
    yc <- 2 # y_c or k
    a <- 5 # major axis length
    b <- 2 # minor axis length
    phi <- pi/3 # angle of major axis with x axis phi or tau
    
    t <- seq(0, 2*pi, 0.01) 
    x <- xc + a*cos(t)*cos(phi) - b*sin(t)*sin(phi)
    y <- yc + a*cos(t)*cos(phi) + b*sin(t)*cos(phi)
    plot(x,y,pch=19, col='blue')
    

    现在,如果我们想从 cartesian conic 等式开始,这是一个两步过程。

    1. cartesian方程转换为polarparametric),形式我们可以使用下面的方程,首先使用下图中的5个方程得到5个参数(取自http://www.cs.cornell.edu/cv/OtherPdf/Ellipse.pdf ,详细的数学可以在那里找到)。

    2. 使用获得的参数绘制椭圆,如上所示。

    对于第 (1) 步,我们可以使用以下代码(当我们知道 A,B,C,D,E,F 时):

    M0 <- matrix(c(F,D/2,E/2, D/2, A, B/2, E/2, B/2, C), nrow=3, byrow=TRUE)
    M <- matrix(c(A,B/2,B/2,C), nrow=2)
    lambda <- eigen(M)$values
    abs(lambda - A)
    abs(lambda - C) 
    
    # assuming abs(lambda[1] - A) < abs(lambda[1] - C), if not, swap lambda[1] and lambda[2] in the following equations:
    
    a <- sqrt(-det(M0)/(det(M)*lambda[1]))  
    b <- sqrt(-det(M0)/(det(M)*lambda[2]))
    xc <- (B*E-2*C*D)/(4*A*C-B^2)
    yc <- (B*D-2*A*E)/(4*A*C-B^2)
    phi <- pi/2 - atan((A-C)/B)*2
    

    对于第 (2) 步,使用以下代码:

    t <- seq(0, 2*pi, 0.01) 
    x <- xc + a*cos(t)*cos(phi) - b*sin(t)*sin(phi)
    y <- yc + a*cos(t)*cos(phi) + b*sin(t)*cos(phi)
    plot(x,y,pch=19, col='blue')
    

    【讨论】:

    • 关于代码本身的三个备注:y &lt;- yc + a * cos(t) * sin(phi) + b * sin(t) * cos(phi) and phi &lt;- (pi/2 - atan((A-C)/B))/2 and xc &lt;- (B*E-2*C*D)/(4*A*C-B^2)
    • 错误:方程(帖子顶部的图像)和 y 的代码之间的差异
    • 从代码中删除了 2 处 y 的错误
    • 对于step2我相信你有错字,应该是:y &lt;- yc + a*cos(t)*sin(phi) + b*sin(t)*cos(phi)
    【解决方案3】:

    当您知道椭圆的中心轴和主轴时,另一个答案向您展示了如何绘制椭圆。但它们在一般椭圆方程中并不明显。所以在这里,我将从头开始。

    省略数学推导,您需要从以下等式求解中心:

    (哎呀:应该是“生成v”而不是“生成u”;我无法修复它,因为原来的LaTeX 现在丢失了,我不想再次输入...... )

    这是一个 R 函数:

    plot.ellipse <- function (a, b, c, d, e, f, n.points = 1000) {
      ## solve for centre
      A <- matrix(c(a, c / 2, c / 2, b), 2L)
      B <- c(-d / 2, -e / 2)
      mu <- solve(A, B)
      ## generate points on circle
      r <- sqrt(a * mu[1] ^ 2 + b * mu[2] ^ 2 + c * mu[1] * mu[2] - f)
      theta <- seq(0, 2 * pi, length = n.points)
      v <- rbind(r * cos(theta), r * sin(theta))
      ## transform for points on ellipse
      z <- backsolve(chol(A), v) + mu
      ## plot points
      plot(t(z), type = "l")
      }
    

    几点说明:

    1. 参数a, b, ..., f 有条件,以确保方程是椭圆而不是其他东西(比如抛物线)。所以,不要传入任意参数值来测试。事实上,从等式中可以大致看出这样的要求。比如矩阵A必须是正定的,所以a &gt; 0det(A) &gt; 0;还有,r ^ 2 &gt; 0
    2. 我使用了 Cholesky 分解,因为这是我最喜欢的。然而,最漂亮的结果来自特征分解。这部分我不再赘述。如果您对此感兴趣,请阅读我的另一个答案Obtain vertices of the ellipse on an ellipse covariance plot (created by car::ellipse)。有漂亮的图来说明 Cholesky 分解和特征分解的几何。

    【讨论】:

    • 很好的答案!问题:为什么原来的问题有一个“f”参数,但你的解决方案没有?会掉线吗?
    • 我的错。我只看了第一个矩阵方程。
    • 因此,如果我添加对正定性的检查,则可以确保用户输入的任何任意参数都适用于椭圆?
    • @curious_cat 这些必须持有:a &gt; 0; 4ab - c^2 &gt; 0;还有,r^2 &gt; 0。这是一个工作示例:plot.ellipse(1, 3, 2, 12, -5, 50)