Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在椭圆或贝兹曲线上查找等距点_Javascript_Math_Geometry_2d - Fatal编程技术网

Javascript 在椭圆或贝兹曲线上查找等距点

Javascript 在椭圆或贝兹曲线上查找等距点,javascript,math,geometry,2d,Javascript,Math,Geometry,2d,目前,我正在编写JavaScript代码,将对象放置在屏幕上的椭圆上 我试图找到解决这个问题的算法,椭圆是完美的,但如果太贵,贝兹曲线也可以 我很抱歉,但不幸的是,我的数学不允许我使用我找到的答案(,),所以我需要帮助将其翻译成代码或只是建议如何做 如果您需要我的问题的可视化,您可以查看本文档的第二页: 好的,我收回了我的近距离投票。你的问题与我链接的问题略有不同 但正如你所看到的那样:) 我已经玩了一点我的代码,所以这里是等距点的结果 //-------------------------

目前,我正在编写JavaScript代码,将对象放置在屏幕上的椭圆上

我试图找到解决这个问题的算法,椭圆是完美的,但如果太贵,贝兹曲线也可以

我很抱歉,但不幸的是,我的数学不允许我使用我找到的答案(,),所以我需要帮助将其翻译成代码或只是建议如何做

如果您需要我的问题的可视化,您可以查看本文档的第二页:

好的,我收回了我的近距离投票。你的问题与我链接的问题略有不同

  • 但正如你所看到的那样:)
我已经玩了一点我的代码,所以这里是等距点的结果

//---------------------------------------------------------------------------
作废提款()
{
TCanvas*scr=Form1->Canvas;
//如果(scr->FHandle==NULL)返回;
scr->画笔->颜色=白色;
scr->矩形(0,0,Form1->ClientWidth,Form1->ClientHeight);
双x0,y0,rx,ry,n,l0,ll0;
x0=Form1->ClientWidth>>1;//椭圆位置(表单中间)
y0=Form1->ClientHeight>>1;
rx=200;//椭圆a
ry=50;//椭圆b
n=33.0;//段
//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));
//计算段大小
l0/=n;ll0=l0*l0;
inti,j,k,kd;
回答问题;
双a,da,x,y,xx,yy,ll,mm,r=2.0;
对于(kd=10,k=0;;k++)//kd+1个过程
{
a=0.0;如果(!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)//仅在最后一次过程中绘制
{
scr->Pen->Color=clRed;
scr->MoveTo(x,y);
scr->LineTo(x0,y0);
scr->椭圆(x-r,y-r,x+r,y+r);
scr->Pen->Color=clBlue;
scr->Font->Color=clBlue;
}
对于(i=n;i>0;i--)
{
//与l0匹配的近似角度步长(作为拟合的起点)
xx=rx*sin(a+0.5*da);
yy=ry*cos(a+0.5*da);
da=l0/sqrt((xx*xx)+(yy*yy));
//下一点位置
xx=x;yy=y;a+=da;
x=x0+rx*cos(a);
y=y0+ry*sin(a);
//使它真正适合l0
ll=((xx-x)*(xx-x))+((yy-y)*(yy-y));ll=fabs(ll0-ll);
对于(da*=0.1,a-=da,j=0;jll){a-=da;da=-0.1*da;j++;}else ll=mm;//如果acuracy停止爱,改变方向
}
x=x0+rx*cos(a);
y=y0+ry*sin(a);
if(k==kd)//仅在最后一次过程中绘制
{
//画线和点
scr->MoveTo(xx,yy);
scr->LineTo(x,y);
scr->椭圆(x-r,y-r,x+r,y+r);
//打印差异^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);
打破
}
//重缩放l0
a=2.0*M_PI/a;//如果没有错误,a应该是2*PI->1.0
l0*=0.5+0.5*a;//只需迭代
ll0=l0*l0;
}
}
//---------------------------------------------------------------------------
它由第二个链接的Q/A的代码组成,但无论如何,它就是这样做的

  • k/kd
    循环整个事情
    kd
    -次

    在每一种情况下,通过重新调整段大小
    l0,ll0
    ,它都会更接近结果。在最后一个过程中,它还会绘制线段。。。传球越多,你获得的精确度就越高。通过电流过冲,它甚至可以处理
    rx=4.0*ry
    偏心椭圆(反之亦然)。对于普通椭圆,只要
    kd=1,2或3就足够了

  • i
    循环遍历所有段

    首先通过链接的Q/A公式进行一步估计,然后通过最内部的“j”循环使用分段大小的迭代拟合到
    l0

  • 最里面的
    j
    loop

    只需步进角度,如果不改变步进方向及其大小,则查看段是否更接近所需大小
    10次
    以提高精度
    j的递归层越多
    越精确

  • k/kd
    循环的末尾

    角度应为
    2*PI
    ,因此,如果角度大于或小于此值,则相应地重新缩放
    l0
    ,但为了避免振荡,也可使用原始
    l0
    大小的平均值


  • 这就是这个问题的全部

    可能的重复是不可解的,代数上你只能找到近似值。这个重复的问题通过迭代来处理,迭代足够精确,但有点慢。另外,如果你不需要非常精确的解,那么现在看看这个简单的近似,如果你想跳过椭圆而使用贝塞尔,这不是一个好主意,因为贝塞尔在这方面更糟糕(只有递归迭代可以解决它)…非常感谢你,对不起,但我在上次搜索中没有发现这个方法,即使做得很深入。感谢您对贝塞尔曲线的解释,这是非常及时的。我不认为这么简单的问题就没有简单的解决方案