在R中给出一般方程如何绘制椭圆?

时间:2017-01-24 05:32:34

标签: r math plot ellipse

椭圆一般方程:

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

enter image description here

3 个答案:

答案 0 :(得分:4)

我们可以从parametric的{​​{1}}等式开始(以下是维基百科),我们需要5个参数:中心ellipse(xc, yc)在另一个表示法,轴长(h,k)以及x轴与长轴a, bphi之间的角度在另一种表示法中。

enter image description here

tau

enter image description here

现在,如果我们想从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') 等式开始,那么这是一个两步过程。

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

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

  3. enter image description here

    对于步骤(1),我们可以使用以下代码(当我们知道parametric时):

    A,B,C,D,E,F

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

    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-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
    

答案 1 :(得分:4)

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

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

enter image description here

enter image description here

(oops:应该是“生成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 > 0det(A) > 0;另外,r ^ 2 > 0
  2. 我使用了Cholesky分解,因为这是我最喜欢的。然而,最美丽的结果来自特征分解。我不会在这方面进一步追求。如果您对此感兴趣,请阅读我的另一个答案Obtain vertices of the ellipse on an ellipse covariance plot (created by car::ellipse)。有很好的数字来说明Cholesky分解和特征分解的几何。

答案 2 :(得分:3)

您可以使用我的软件包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)

enter image description here