Find equidistant points on an ellipse or basieux curves

I am currently writing JavaScript code that will place objects on the screen in an ellipse.

I am trying to find an algorithm that will solve one of these problems, the ellipse will be perfect, but if it is too expensive, the Beisier curve will be fine too.

Sorry, but fortunately my math does not allow me to use the answers I found ( https://mathoverflow.net/questions/28070/finding-n-points-that-are-equidistant-around-the-circumference-of -an-ellipse , Differential points on Bezier curves ), so I need help to translate it into code or just advice on how to do this.

If you need visualization of my question, you can see the second page of this document: http://www.saccade.com/writing/graphics/RE-PARAM.PDF

-1
source share
1 answer

Ok, I removed my closed voice, your question is a little different from the ones I am related to

  • but as you can see not much :)

We played with my code a bit, so here is the result for equidistant points

//---------------------------------------------------------------------------
void draw()
    {
    TCanvas *scr=Form1->Canvas;
    //if (scr->FHandle==NULL) return;
    scr->Brush->Color=clWhite;
    scr->Rectangle(0,0,Form1->ClientWidth,Form1->ClientHeight);

    double x0,y0,rx,ry,n,l0,ll0;
    x0=Form1->ClientWidth>>1;   // ellipse position (midle of form)
    y0=Form1->ClientHeight>>1;
    rx=200;                     // ellipse a
    ry=50;                      // ellipse b
    n=33.0;                     // segments
    //l0=2.0*M_PI*sqrt(0.5*((rx*rx)+(ry*ry)));
    l0=(rx-ry)/(rx+ry); l0*=3.0*l0; l0=M_PI*(rx+ry)*(1.0+(l0/(10.0+sqrt(4.0-l0))));
    // compute segment size
    l0/=n; ll0=l0*l0;

    int i,j,k,kd;
    AnsiString s;
    double a,da,x,y,xx,yy,ll,mm,r=2.0;

    for (kd=10,k=0;;k++)    // kd+1 passes
        {
        a=0.0; if (!k) da=0.0;
        xx=rx*sin(a+0.5*da);
        yy=ry*cos(a+0.5*da);
        da=l0/sqrt((xx*xx)+(yy*yy));
        x=x0+rx*cos(a);
        y=y0+ry*sin(a);
        if (k==kd) // draw in last pass only
            {
            scr->Pen->Color=clRed;
            scr->MoveTo(x ,y );
            scr->LineTo(x0,y0);
            scr->Ellipse(x-r,y-r,x+r,y+r);
            scr->Pen->Color=clBlue;
            scr->Font->Color=clBlue;
            }
        for (i=n;i>0;i--)
            {
            // approximate angular step to match l0 (as start point for fitting)
            xx=rx*sin(a+0.5*da);
            yy=ry*cos(a+0.5*da);
            da=l0/sqrt((xx*xx)+(yy*yy));
            // next point position
            xx=x; yy=y; a+=da;
            x=x0+rx*cos(a);
            y=y0+ry*sin(a);

            // fit it to be really l0
            ll=((xx-x)*(xx-x))+((yy-y)*(yy-y)); ll=fabs(ll0-ll);
            for (da*=0.1,a-=da,j=0;j<5;) // accuracy recursion layers
                {
                a+=da;
                x=x0+rx*cos(a);
                y=y0+ry*sin(a);
                mm=((xx-x)*(xx-x))+((yy-y)*(yy-y)); mm=fabs(ll0-mm);
                if (mm>ll) { a-=da; da=-0.1*da; j++; } else ll=mm;  // if acuracy stop lovering change direction
                }
            x=x0+rx*cos(a);
            y=y0+ry*sin(a);

            if (k==kd) // draw in last pass only
                {
                // draw the lines and dots
                scr->MoveTo(xx,yy);
                scr->LineTo(x ,y );
                scr->Ellipse(x-r,y-r,x+r,y+r);
                // print the difference^2
                ll=((xx-x)*(xx-x))+((yy-y)*(yy-y));
                s=AnsiString().sprintf("%.2lf",ll0-ll);
                xx=0.5*(x+xx)+20.0*cos(a)-0.5*double(scr->TextWidth(s));
                yy=0.5*(y+yy)+20.0*sin(a)-0.5*double(scr->TextHeight(s));
                scr->TextOutA(xx,yy,s);
                }
            }
        if (k==kd)
            {
            scr->MoveTo(x ,y );
            scr->LineTo(x0,y0);
            s=AnsiString().sprintf("%.4lf",2.0*M_PI-a);
            xx=x+60.0*cos(a)-0.5*double(scr->TextWidth(s));
            yy=y+60.0*sin(a)-0.5*double(scr->TextHeight(s));
            scr->TextOutA(xx,yy,s);
            break;
            }
        // rescale l0
        a=2.0*M_PI/a;       // a should be 2*PI if no error -> 1.0
        l0*=0.5+0.5*a;      // just iterate
        ll0=l0*l0;
        }
    }
//---------------------------------------------------------------------------

It consists of code from a second linked Q / A , but in any case this is what it does

  • k/kdthe loop completes all kd-times

    , l0,ll0. ... , . rx=4.0*ry ( ). , kd=1,2 or 3

  • i

    Q/A, l0 'j'

  • j

    , , 10 , , j,

  • k/kd

    2*PI, , l0, , , l0

ellipse result

0

Source: https://habr.com/ru/post/1678438/


All Articles