Given a conic coefficient matrix that we can assume that represents an ellipse, in homogeneous coordinates:
import numpy as np
Q = np.array([[ a, b/2, d/2],
[b/2, c, e/2],
[d/2, e/2, f]])
Q = Q / Q[2,2] # Divide everything by f, to scale for centre
How can I find, the:
- Centre of ellipse (centre_x, centre_y)?
- Length of major and minor axis?
- Angle of ellipse relative to x?
According to this answer, the centre is just the last row/column of Q*. Is this correct?
Also to find the length of the major and minor axis, I have found some suggestions to use the eigenvalues/eigenvectors, but I am not sure how could I do that in practice. Can I calculate the eigenvalues/eigenvectors of the top 2×2 part of Q
and use that information to calculate the lengths?
For the angle I think probably the eigenvector can also indicate the direction of the major axis, is this true?
Edit
Using the below answer and @Ng Chung Tak comment. I ended up with the following code:
# Get the coefficients
A = Q[0, 0]
B = Q[0, 1] * 2.0
C = Q[1, 1]
D = Q[0, 2] * 2.0
E = Q[1, 2] * 2.0
F = Q[2, 2]
# Check if it is indeed an ellipse
if np.linalg.det(Q) == 0:
raise ValueError("Degenerate conic found!")
if np.linalg.det(Q[:2,:2]) <= 0: # According to Wikipedia
raise ValueError("These parameters do not define an ellipse!")
# Get centre
denominator = B**2 - 4*A*C
centre_x = (2*C*D - B*E) / denominator
centre_y = (2*A*E - B*D) / denominator
print("Centre x:{} y:{}".format(centre_x, centre_y))
# Get major and minor axes
K = - np.linalg.det(Q[:3,:3]) / np.linalg.det(Q[:2,:2])
root = math.sqrt(((A - C)**2 + B**2))
a = math.sqrt(2*K / (A + C - root))
b = math.sqrt(2*K / (A + C + root))
print("Major:{} minor:{}".format(a, b))
# Get angle
angle = math.atan2(C - A + root, B)
angle *= 180.0/math.pi # Convert angle to degrees
print("Angle in degrees: {}".format(angle))
Example of projecting a red sphere into an ellipse and then drawing the ellipse in green:
Best Answer
Here is an answer in Python language: