5

I have n circles that must be perfectly surrounding an ellipse as shown in the picture here :

Ellipse & Circles

In this picture I need to find out the position of each circle around the ellipse, and also be able to calculate the ellipse that will fit perfectly inside those surrounding circles.

The information i know is the radius of each circles (all same), and the number of circles.

Hopefully this time the post is clear. Thanks for your help. Please let me know if you need more explanation.

Dennis Meng
  • 5,109
  • 14
  • 33
  • 36
user2360915
  • 1,100
  • 11
  • 30
  • 1
    That's some awesome ASCII art! To post pictures, it needs to be hosted on another site and you reference it with markdown. See [this reference](http://daringfireball.net/projects/markdown/basics). – beatgammit Oct 24 '13 at 03:58
  • Thanks. Didnt think about hosting the picture somewhere else. I updated the post, it should be better now. – user2360915 Oct 24 '13 at 04:16
  • very interesting problem what are the ellipse parameters ??? must be it an ellipse or is there some eccentricity limit ??? can it be also a circle ??? – Spektre Oct 24 '13 at 06:34
  • Hi, Spektre. Yes, it must an ellipse. If it is a circle, then I know the solution using the cosine law, and regular polygon. If it is an ellipse, it seems more difficult. The parameters of the ellipse must be found and be based on the radius "r" of the "N" surrounding circles. – user2360915 Oct 24 '13 at 06:43
  • I'm affraid this is more of a mathematical question. Still interested by the question. – Fabinout Oct 24 '13 at 08:07
  • Yes, I agree about the math problem. I need to transform this problem into some algo. – user2360915 Oct 24 '13 at 09:25
  • I think mathematics is needed but because of this has no algebraic solution (we cannot compute the length of ellipse precise nor the bounding polygon fit) the programming is the only solution left (genere/test, or in my case try and add to improve accuracy iteration) of course i could miss some basic formula behind it ... so if there is one please share it with us not en-lighted yet :) – Spektre Oct 25 '13 at 06:44
  • ow and one last comment firstly i try just to distort circle case but the result is not fitted to ellipse precise enough so do not go this way. – Spektre Oct 25 '13 at 06:56

1 Answers1

3

OK as i understand you know common radius of circles R0 and their number N and want to know inside ellipse parameters and positions of everything.

If we convert ellipse to circle then we get this:

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]

For ellipse its a whole new challenge (took me two hours to find all quirks out)

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

Well I know its a little messy code so here is some info:

  1. first it try to set as close ellipse rx,ry axises as possible

    ellipse length should be about N*R*2 which is polygon length of lines between circle centers

  2. try to compose circles so they are touching each other and the ellipse

    I use iteration of ellipse angle for that. Problem is that circles do not touch the ellipse in their position angle thats why there is q variable ... to compensate around ellipse normal. Look for yellowish-golden lines in image

  3. after placing circles check if the last one is touching the first

    if not interpolate the size of ellipse actually it scales the rx,ry by m variable up or down

  4. you can adjust accuracy

    by change of the j,k fors and/or change of dm,da scaling factors

  5. input parameter E should be at least 0.5 and max 1.0

    if not then there is high probability of misplacing circles because on very eccentric ellipses is not possible to fit circles (if N is too low). Ideal setting is 0.7<=E<=1.0 closser to 1 the safer the algorithm is

  6. atanxy(dx,dy) is the same as `atan(dy/dx)

    but it handles all 4 quadrants like atan2(dy,dx) by sign analysis of dx,dy

Ellipse + circles

Hope it helps

Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380
  • Spektre, thanks, you understood what I want and what i know. However, I knew how to get x & y for each satellites in case of a circle. This case is easy because the center of each satellites make a regular polygon around the inside circle. In case of ellipse, it is not because each angle will be different. x & y cant be found by using cos & sin. – user2360915 Oct 24 '13 at 09:23
  • Excellent. Thanks a lot. Code is messy but I got the idea. Thanks. – user2360915 Oct 25 '13 at 05:16
  • 1
    if you need to use E<0.7 then you should change the q computation (first try to place 2 circles and then use the mid angle between center lines between previous and next circle) this is more precise for smaller E because of higher accuracy losses for smaller E – Spektre Oct 25 '13 at 06:38