0

This question is similar to the question, How to fit a 2D ellipse (in x-y plane) to given points? (See the link below) (How to fit a 2D ellipse to given points)

Now, we know how to use least square method to fit a 2D ellipse with given points by the code provided by Casey. (The code is also provided below.) Based on this code, if I want to fit not only the given points but also a given focus at (0,0), how could I do it? Or is there any better way to do it?

I was thinking about if we can derive the focus (as a function of x and y) based on the ellipse equation, Ax^2 + Bxy + Cy^2 + Dx + Ey=1 , where A, B, C, D, E are coefficients, and use it as a constrain to the least square method. Buts sadly, I don't know how to derive the focus either.

CODE

import numpy as np
import matplotlib.pyplot as plt
alpha = 5
beta = 3
N = 500
DIM = 2

np.random.seed(2)

# Generate random points on the unit circle by sampling uniform angles
theta = np.random.uniform(0, 2*np.pi, (N,1))
eps_noise = 0.2 * np.random.normal(size=[N,1])
circle = np.hstack([np.cos(theta), np.sin(theta)])

# Stretch and rotate circle to an ellipse with random linear tranformation
B = np.random.randint(-3, 3, (DIM, DIM))
noisy_ellipse = circle.dot(B) + eps_noise

# Extract x coords and y coords of the ellipse as column vectors
X = noisy_ellipse[:,0:1]
Y = noisy_ellipse[:,1:]

# Formulate and solve the least squares problem ||Ax - b ||^2
A = np.hstack([X**2, X * Y, Y**2, X, Y])
b = np.ones_like(X)
x = np.linalg.lstsq(A, b)[0].squeeze()

# Print the equation of the ellipse in standard form
print('The ellipse is given by {0:.3}x^2 + {1:.3}xy+{2:.3}y^2+{3:.3}x+{4:.3}y = 1'.format(x[0], x[1],x[2],x[3],x[4]))

# Plot the noisy data
plt.scatter(X, Y, label='Data Points')

# Plot the original ellipse from which the data was generated
phi = np.linspace(0, 2*np.pi, 1000).reshape((1000,1))
c = np.hstack([np.cos(phi), np.sin(phi)])
ground_truth_ellipse = c.dot(B)
plt.plot(ground_truth_ellipse[:,0], ground_truth_ellipse[:,1], 'k--', label='Generating Ellipse')

# Plot the least squares ellipse
x_coord = np.linspace(-5,5,300)
y_coord = np.linspace(-5,5,300)
X_coord, Y_coord = np.meshgrid(x_coord, y_coord)
Z_coord = x[0] * X_coord ** 2 + x[1] * X_coord * Y_coord + x[2] * Y_coord**2 + x[3] * X_coord + x[4] * Y_coord
plt.contour(X_coord, Y_coord, Z_coord, levels=[1], colors=('r'), linewidths=2)

plt.legend()
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
  • If you get the equation from the points, what's the problem with finding the coordinates of the foci? – Mad Physicist Jan 14 '21 at 05:27
  • The foci from the equation may not be at (0,0). I am trying to find a ellipse that is best-fit to the points and with a focus at (0,0). – Blake Chang Jan 14 '21 at 05:32
  • Write the equation of the ellipse in terms of the other final point and whatever other parameters you need. Probably just major axis. That's three parameters to solve for, since you fixed two of the five. – Mad Physicist Jan 14 '21 at 08:02
  • Thank you so much for your reply. I am working on that. – Blake Chang Jan 15 '21 at 06:20

1 Answers1

0

For a ellipse with a focus at (0,0), the ellipse's equation in polar coordinate can be written as the following:

Given = semi-major axis, = eccentricity, the other focus at the angle ,

enter image description here

Now, we can use the data points (,) to fit the equation above by non-linear least square method (ex: Levenberg–Marquardt algorithm).

i.e. Find the minimum for the following equation:

enter image description here