Отстойные, но довольно быстрые, способы — через решение систем уравнений влоб. Типа, окружность по трем точкам, эллипс по восьми (?) точкам, перебираем комбинации все/случайным образом и усредняем результат. То, что предлагает mayorovp вторым пунктом. Почему отстойные — устойчивость плохая. Именно так мы делаем у себя — способы действительно отстойные и требуют костылей, но действительно быстрые. Разница между реальным центром и найденным таким способом намного меньше пикселя, но костылей действительно много. Например, отбирая треугольник при поиске окружности по 3-м точкам, нужно, чтобы все три точки были из разных четвертей окружности.
Я не рекомендую — кода много, а экономия оправдывает себя только на железе 20 летней давности, когда нужен околорилтайм. Для эллипса по-моему малореально вообще что-либо нормальное получить.
Универсальный способ — метод наименьших квадратов. То есть заставить компьютер подобрать такие параметры эллипса чтобы разница между эллипсом и нашими точками была минимальной. Лучше критерий сложно придумать — хотя иногда получается не то, что ожидаешь, но это скорее говорит о том, что исходные данные неправильные.
Алгоритм такой:
1. Выбираем подходящее уравнение эллипса.
2. Пишeм целевую функцию (сумма квадратов уравнения для каждой точки исходных данных). По необходимости добавляем к целевой функции дополнительные условия, типа невырождаемости эллипса в гиперболу. Типа, если условие нарушается, устремляем ее в бесконечность.
3. Выбираем минимизатор (градиентный спуск, нормальное уравнение т. д.)
4. Если результаты не устраивают по скорости или качеству, возвращаемся к п. 3 или к п. 1.
По поводу третьего пункта. В России почему-то считается, что МНК — это когда решение идет с помощью нормального уравнения (составляем матрицы и решаем (AtA)^-1*At*x=b без итераций в один присест). Это не так. Минимизировать можно каким угодно способом. Хоть генетическими алгоритмами. Нормальное уравнение хорошо тогда, когда член (AtA)^-1 получается маленькой квадратной матрицей. То есть когда параметров мало, а точек очень много. Систему уравнений для эллипса вообще к виду A*x-b=0 привести служно. Искать соответствующие статьи как это делается мне влом, поэтому я пойду влоб, в качестве минимизатора взяв стандартный матлабовский.
Используя формулы mayorovp.
%точки
xs = [1 2 3 4 5 6 7 8 9 10];
ys = [11 10 9 7 5 4 3 2 1 1];
%сначала приблизим окружностью - чтобы не вырождалось в гиперболу
%уравнение окружности
circ = @(xs, ys, x0, y0, Rsq) (xs - x0).^2 + (ys - y0).^2 - Rsq;
%целевая функция МНК
fitfunc1 = @(X) sum( ( circ(xs, ys, X(1), X(2), X(3)) ) .^2 );
%начальное приближение
x0 = mean(xs);
y0 = mean(ys);
R = 1;
result1 = fminsearch(fitfunc1, [x0 y0 R], optimset('display', 'iter'));
%уравнение эллипса
ellipse = @(xs, ys, x0, y0, A, B, C, F) A*(xs-x0).^2 + B*(xs-x0).*(ys-y0) + C*(ys-y0).^2 - F;
%целевая функция МНК
fitfunc2 = @(X) sum( ( ellipse(xs, ys, X(1), X(2), X(3), X(4), X(5), X(6))) .^2 );
%начальное приближение - найденная окружность
x0 = result1(1);
y0 = result1(2);
A = 1;
B = 0;
C = 1;
F = result1(3);
%сумма квадратов целевой функции для каждой точки
result = fminsearch(fitfunc2, [x0 y0 A B C F], optimset('display', 'iter'));
figure
hold on;
%изначальные точки
scatter(xs, ys,'b');
%эллипс
xs1 = -2:0.005:20;
ys1 = -2:0.005:20;
[xss yss] = meshgrid(xs1, ys1);
ell = abs(ellipse(xss(:), yss(:), result(1), result(2), result(3), result(4), result(5), result(6)) ) < 0.0001;
scatter(xss(ell), yss(ell),'r');