ОК, как я понимаю, вы знаете общий радиус окружностей R0 и их число N и хотите знать внутренние параметры эллипса и положения всего.
Если мы преобразуем эллипс в круг, то мы получим следующее:
const int N=12; // number of satelite circles
const double R=10.0; // radius of satelite circles
struct _circle { double x,y,r; } circle[N]; // satelite circles
int i;
double x,y,r,l,a,da;
x=0.0; // start pos of first satelite circle
y=0.0;
r=R;
l=r+r; // distance ang angle between satelite circle centers
a=0.0*deg;
da=divide(360.0*deg,N);
for (i=0;i<N;i++)
{
circle[i].x=x; x+=l*cos(a);
circle[i].y=y; y+=l*sin(a);
circle[i].r=r; a+=da;
}
// inside circle params
_circle c;
r=divide(0.5*l,sin(0.5*da))-R;
c.x=circle[i].x;
c.y=circle[i].y+R+r;
c.r=r;
[Edit 1]
Для эллипса его совершенно новый вызов (взял меня за два часа до найти все причуды)
const int N=20; // number of satelite circles
const double R=10.0; // satelite circles radius
const double E= 0.7; // ellipse distortion ry=rx*E
struct _circle { double x,y,r; _circle() { x=0; y=0; r=0.0; } } circle[N];
struct _ellipse { double x,y,rx,ry; _ellipse() { x=0; y=0; rx=0.0; ry=0.0; } } ellipse;
int i,j,k;
double l,a,da,m,dm,x,y,q,r0;
l=double(N)*R; // circle cener lines polygon length
ellipse.x =0.0; // set ellipse parameters
ellipse.y =0.0;
r0=divide(l,M_PI*sqrt(0.5*(1.0+(E*E))))-R;// aprox radius to match ellipse length for start
l=R+R; l*=l;
m=1.0; dm=1.0; x=0.0;
for (k=0;k<5;k++) // aproximate ellipse size to the right size
{
dm=fabs(0.1*dm); // each k-iteration layer is 10x times more accurate
if (x>l) dm=-dm;
for (;;)
{
ellipse.rx=r0 *m;
ellipse.ry=r0*E*m;
for (a=0.0,i=0;i<N;i++) // set circle parameters
{
q=(2.0*a)-atanxy(cos(a),sin(a)*E);
circle[i].x=ellipse.x+(ellipse.rx*cos(a))+(R*cos(q));
circle[i].y=ellipse.y+(ellipse.ry*sin(a))+(R*sin(q));
circle[i].r=R;
da=divide(360*deg,N); a+=da;
for (j=0;j<5;j++) // aproximate next position to match 2R distance from current position
{
da=fabs(0.1*da); // each j-iteration layer is 10x times more accurate
q=(2.0*a)-atanxy(cos(a),sin(a)*E);
x=ellipse.x+(ellipse.rx*cos(a))+(R*cos(q))-circle[i].x; x*=x;
y=ellipse.y+(ellipse.ry*sin(a))+(R*sin(q))-circle[i].y; y*=y; x+=y;
if (x>l) for (;;) // if too far dec angle
{
a-=da;
q=(2.0*a)-atanxy(cos(a),sin(a)*E);
x=ellipse.x+(ellipse.rx*cos(a))+(R*cos(q))-circle[i].x; x*=x;
y=ellipse.y+(ellipse.ry*sin(a))+(R*sin(q))-circle[i].y; y*=y; x+=y;
if (x<=l) break;
}
else if (x<l) for (;;) // if too short inc angle
{
a+=da;
q=(2.0*a)-atanxy(cos(a),sin(a)*E);
x=ellipse.x+(ellipse.rx*cos(a))+(R*cos(q))-circle[i].x; x*=x;
y=ellipse.y+(ellipse.ry*sin(a))+(R*sin(q))-circle[i].y; y*=y; x+=y;
if (x>=l) break;
}
else break;
}
}
// check if last circle is joined as it should be
x=circle[N-1].x-circle[0].x; x*=x;
y=circle[N-1].y-circle[0].y; y*=y; x+=y;
if (dm>0.0) { if (x>=l) break; }
else { if (x<=l) break; }
m+=dm;
}
}
Ну я знаю его немного грязный код так вот некоторая информация:
сначала попытаться установить как можно ближе Эллипс Rx, Ry осях как можно
длина эллипса должна составлять около N*R*2
который длина полигона линий между центрами окружностей
пытаются сочинить круги, чтобы они касались друг друга, и эллипс
Я использую для этого итерацию угла эллипса. Проблема в том, что круги не касаются эллипса в своем угловом положении, поэтому переменная q
... компенсирует нормальный эллипс.Посмотрите на желто-золотые линии в изображении
после размещения кругов проверить, если последний прикасаются первым
если не интерполировать размер эллипса фактически масштабирование rx,ry
по m
переменного вверх или вниз
вы можете настроить Точность
путем изменения j,k
for
сек ап д/или изменение dm,da
коэффициентов масштабирования
входной параметр E
должен быть по крайней мере 0.5
и максимальная 1.0
если нет, то существует высокая вероятность кладя кругов, потому что на очень эксцентричных эллипсов не представляется возможным, чтобы соответствовать круги (если N
слишком низок). Идеальная настройка 0.7<=E<=1.0
closser к 1, тем безопаснее алгоритм
atanxy(dx,dy)
так же, как `Atan (ду/дх)
но он обрабатывает все 4 квадранта, как atan2(dy,dx)
с помощью знака анализа dx,dy
Надеется, что это помогает
Это потрясающее искусство ASCII! Чтобы отправлять фотографии, их нужно размещать на другом сайте, и вы ссылаетесь на него с уценкой. См. [Эта ссылка] (http://daringfireball.net/projects/markdown/basics). – tjameson
Спасибо. Не думал о размещении картины где-то в другом месте. Я обновил сообщение, теперь должно быть лучше. – user2360915
очень интересная проблема, каковы параметры эллипса ??? должно быть, это эллипс или есть ли какой-то предел эксцентриситета ??? может ли это быть и кругом ??? – Spektre