2013-10-24 3 views
5

У меня есть п круги, которые должны быть идеально окружающим эллипс, как показано на рисунке здесь:алгоритма для вычисления формы (Эллипс)

Ellipse & Circles

В этой картине мне нужно выяснить позицию каждого круга вокруг эллипса, а также сможете вычислить эллипс, который идеально поместится в окружающих кругах.

Информация, которую я знаю, - это радиус каждого круга (все то же самое) и количество кругов.

Надеюсь, на этот раз сообщение ясно. Спасибо за помощь. Пожалуйста, дайте мне знать, если вам нужно больше объяснений.

+1

Это потрясающее искусство ASCII! Чтобы отправлять фотографии, их нужно размещать на другом сайте, и вы ссылаетесь на него с уценкой. См. [Эта ссылка] (http://daringfireball.net/projects/markdown/basics). – tjameson

+0

Спасибо. Не думал о размещении картины где-то в другом месте. Я обновил сообщение, теперь должно быть лучше. – user2360915

+0

очень интересная проблема, каковы параметры эллипса ??? должно быть, это эллипс или есть ли какой-то предел эксцентриситета ??? может ли это быть и кругом ??? – Spektre

ответ

3

ОК, как я понимаю, вы знаете общий радиус окружностей 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; 

Circle + circles

[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; 
     } 
    } 

Ну я знаю его немного грязный код так вот некоторая информация:

  1. сначала попытаться установить как можно ближе Эллипс Rx, Ry осях как можно

    длина эллипса должна составлять около N*R*2 который длина полигона линий между центрами окружностей

  2. пытаются сочинить круги, чтобы они касались друг друга, и эллипс

    Я использую для этого итерацию угла эллипса. Проблема в том, что круги не касаются эллипса в своем угловом положении, поэтому переменная q ... компенсирует нормальный эллипс.Посмотрите на желто-золотые линии в изображении

  3. после размещения кругов проверить, если последний прикасаются первым

    если не интерполировать размер эллипса фактически масштабирование rx,ry по m переменного вверх или вниз

  4. вы можете настроить Точность

    путем изменения j,kfor сек ап д/или изменение dm,da коэффициентов масштабирования

  5. входной параметр E должен быть по крайней мере 0.5 и максимальная 1.0

    если нет, то существует высокая вероятность кладя кругов, потому что на очень эксцентричных эллипсов не представляется возможным, чтобы соответствовать круги (если N слишком низок). Идеальная настройка 0.7<=E<=1.0 closser к 1, тем безопаснее алгоритм

  6. atanxy(dx,dy) так же, как `Atan (ду/дх)

    но он обрабатывает все 4 квадранта, как atan2(dy,dx) с помощью знака анализа dx,dy

Ellipse + circles

Надеется, что это помогает

+0

Спектр, спасибо, ты понял, чего я хочу и что знаю. Тем не менее, я знал, как получить x & y для каждого спутника в случае круга. Этот случай прост, потому что центр каждого спутника создает правильный многоугольник вокруг внутреннего круга. В случае эллипса это происходит не потому, что каждый угол будет другим. x & y can not можно найти, используя cos & sin. – user2360915

+1

я отредактировал мой ответ .. добавил случай эллипса – Spektre

+0

Отлично. Большое спасибо. Код грязный, но я понял. Благодарю. – user2360915

Смежные вопросы