Алексей, спасибо что продолжаете попытки усовершенствовать алгоритм.
Я написал функцию возвращающую центр дуги и тестирую ее. Пока что удается ее завалить.
Суть этой функции в этом уравнении
![$L(x,y;u,v,\xi)=\frac{x}{a^2}u+\frac{y}{b^2}v+\left(\frac1{a^2}-\frac1{b^2}\right)xy\,\xi-0.5\cdot(\frac{x^2}{a^2}+ \frac{y^2}{b^2}-1) = 0 $L(x,y;u,v,\xi)=\frac{x}{a^2}u+\frac{y}{b^2}v+\left(\frac1{a^2}-\frac1{b^2}\right)xy\,\xi-0.5\cdot(\frac{x^2}{a^2}+ \frac{y^2}{b^2}-1) = 0](https://dxdy-04.korotkov.co.uk/f/7/e/5/7e5b60da639d21eeaea48fde0595797182.png)
обозначим это уравнение - (!!)
вот код, реализующий это уравнение:
Код:
a2 = a*a; b2 = b*b; A = x/a2; B = y/b2;
C = (1/a2 - 1/b2)*x.*y;
D = -(x.*x/a2 + y.*y/b2 - 1)/2;
M = [A B C D]; X = pere_slau(M);
Mo.X = -X(1); Mo.Y = -X(2); fi = X(3);
Т.е. аппроксимация ведется (пока) по всем точкам дуги и нахожу ее центр Мо и угол наклона fi.
Затем получаю матрицу поворота и переноса
Код:
Mper = [1 0 -Mo.X; 0 1 -Mo.Y; 0 0 1];
s = sin(fi); c = cos(fi);
Mpov = [c s 0; -s c 0; 0 0 1];
MT = Mpov*Mper;
Затем с ее (МТ) помощью переношу все точки дуги и повторяю процедуру нахождения Мо и fi. Это совсем краткое описание (могу это развернуть и подробно по шагам описать)
Главное вывод: любую (с некоторыми пока до конца не ясными ограничениями) дугу можно аппроксимировать эллипсом с произвольно заданными длинами осей. Уравнение (!!) дает такую возможность (должно дать). Полученный результат дает примерно то же самое как и аппроксимация набора точек на плоскости окружностью
(Оффтоп)
Код:
function [Mo R] = approx_circle(x, y)
N = length(x); k = 1/N; k2 = 2*k;
sumx = sum(x); sumy = sum(y);
x2 = x.*x; x3 = x.*x2; sumx2 = sum(x2); sumx3 = sum(x3);
y2 = y.*y; y3 = y.*y2; sumy2 = sum(y2); sumy3 = sum(y3);
sumxy = sum(x.*y);
sumx2y2 = sum(x2+y2);
sumxy2 = sum(x.*y2);
sumx2y = sum(x2.*y);
sumX = sumx2y2*sumx;
sumY = sumx2y2*sumy;
a1 = k2*sumx*sumx - 2*sumx2;
b1 = k2*sumx*sumy - 2*sumxy;
b2 = k2*sumy*sumy - 2*sumy2;
c1 = sumx3 + sumxy2 - k*sumX;
c2 = sumy3 + sumx2y - k*sumY;
xo = (b1*c2 - c1*b2)/(a1*b2 - b1*b1);
yo = (b1*c1 - a1*c2)/(a1*b2 - b1*b1); Mo.X = xo; Mo.Y = yo;
R = sqrt(xo*xo + yo*yo + k*sumx2y2 - k2*(xo*sumx + yo*sumy));
end
эта ф-ция работает всегда, важно только чтобы точки не лежали на одной прямой и чтобы точек было больше двух. Надежность в этом деле самое главное. По ходу тестирования у меня возникает масса трудностей. Раз вы еще здесь, то поделюсь ими.
На самом деле ур-е (!!) применяется не к исходным координатам дуги, а к уже перенесенным за счет нулевого приближения. Это большой недостаток этого метода, т.к. не всегда просто найди это нулевое приближение. Может быть возможно было бы в самое исходное ур-е эллипса подставить скажем не
![$x_1 = x - x_0$, а $x_1 = x - x_0 - \delta x$ $x_1 = x - x_0$, а $x_1 = x - x_0 - \delta x$](https://dxdy-04.korotkov.co.uk/f/3/1/b/31bca0a06e132755a4c5ad0d48544c0d82.png)
тоже самое с
![$y_1$ $y_1$](https://dxdy-04.korotkov.co.uk/f/f/7/0/f7019b486d7fc8f840b0ce0bb0d4171482.png)
и с
![$\varphi$ $\varphi$](https://dxdy-01.korotkov.co.uk/f/4/1/7/417a5301693b60807fa658e5ef9f953582.png)
, т.е. вместо
![$\varphi$ $\varphi$](https://dxdy-01.korotkov.co.uk/f/4/1/7/417a5301693b60807fa658e5ef9f953582.png)
подставить
![$\varphi - $\delta\varphi$ $\varphi - $\delta\varphi$](https://dxdy-02.korotkov.co.uk/f/9/7/8/978f0b26e238e7c4e68912a0a9be8ac282.png)
и получим не это:
![$(\frac{cos(\varphi)^2}{a^2}+\frac{sin(\varphi)^2}{b^2}) \cdot x^2+(\frac{sin(\varphi)^2}{a^2}+\frac{cos(\varphi)^2}{b^2}) \cdot y^2-2\cdot(\frac{cos(\varphi)sin(\varphi)}{a^2}-\frac{cos(\varphi)sin(\varphi)}{b^2})\cdot xy +2 \cdot (-\frac{x0 cos(\varphi)}{a^2}+\frac{y0 sin(\varphi)}{b^2}) \cdot x+2 \cdot (\frac{x0 sin(\varphi)}{a^2}+\frac{y0 cos(\varphi)}{b^2}) \cdot y+(\frac{x0^2}{a^2}+\frac{y0^2}{b^2}-1)=0$ $(\frac{cos(\varphi)^2}{a^2}+\frac{sin(\varphi)^2}{b^2}) \cdot x^2+(\frac{sin(\varphi)^2}{a^2}+\frac{cos(\varphi)^2}{b^2}) \cdot y^2-2\cdot(\frac{cos(\varphi)sin(\varphi)}{a^2}-\frac{cos(\varphi)sin(\varphi)}{b^2})\cdot xy +2 \cdot (-\frac{x0 cos(\varphi)}{a^2}+\frac{y0 sin(\varphi)}{b^2}) \cdot x+2 \cdot (\frac{x0 sin(\varphi)}{a^2}+\frac{y0 cos(\varphi)}{b^2}) \cdot y+(\frac{x0^2}{a^2}+\frac{y0^2}{b^2}-1)=0$](https://dxdy-01.korotkov.co.uk/f/c/2/4/c249978f113cfd70b275435ccfb5f9b182.png)
а нечто гораздо сложнее. Но может быть его можно упростить за счет отбрасывания малых членов
![$\delta x$ $ \delta y$ $\delta \varphi$ $\delta x$ $ \delta y$ $\delta \varphi$](https://dxdy-03.korotkov.co.uk/f/a/8/3/a83b779a974835616220077765127f5282.png)
Если бы это удалось сделать, то тогда бы нулевое приближение было бы не нужным! Но пришлось бы с самого начала находить
![$x_0$ $\delta x$ $y_0$ $\delta y$ $\varphi $ $\delta \varphi$ $x_0$ $\delta x$ $y_0$ $\delta y$ $\varphi $ $\delta \varphi$](https://dxdy-02.korotkov.co.uk/f/5/9/9/59989bc7a2bcb044e4e5b06b81d9f86882.png)
Впрочем может быть это мои иллюзии ибо как можно с самого начала отделить
![$x_0$ $x_0$](https://dxdy-03.korotkov.co.uk/f/e/7/1/e714a3139958da04b41e3e607a54445582.png)
и
![$\delta x$ $\delta x$](https://dxdy-03.korotkov.co.uk/f/a/1/e/a1eec42aa4b134c1ddab6d3e95170fa682.png)
и т.д. ?