查找椭圆或贝塞尔曲线上的等距点

2024-05-01

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

我试图找到能够解决这个问题之一的算法,椭圆将是完美的,但如果它太昂贵,贝塞尔曲线也可以。

抱歉,但不幸的是我的数学不允许我使用我找到的答案(https://mathoverflow.net/questions/28070/finding-n-points-that-are-equidistant-around-the-circumference-of-an-ellipse https://mathoverflow.net/questions/28070/finding-n-points-that-are-equidistant-around-the-circumference-of-an-ellipse , 贝塞尔曲线上的等距点 https://stackoverflow.com/questions/10477/equidistant-points-across-bezier-curves),所以我需要帮助将其转换为代码,或者只是建议如何做到这一点。

如果您需要可视化我的问题,您可以查看本文档的第二页:http://www.saccade.com/writing/graphics/RE-PARAM.PDF http://www.saccade.com/writing/graphics/RE-PARAM.PDF


好吧,我撤回了我的接近投票,你的问题与我链接的问题略有不同

  • 但正如你所看到的,不多:)

玩过我的代码,所以这是等距点的结果

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

它由第二个链接的代码组成Q/A但无论如何,这就是它的作用

  1. k/kd循环循环整个事情kd-times

    在每个中,通过重新调整段大小,它会更接近结果l0,ll0。在最后一遍中,它还绘制了线段……遍数越多,获得的精度就越高。以目前的过度杀伤力,它甚至可以处理rx=4.0*ry偏心椭圆(或反之亦然)。对于常见的椭圆就足够了kd=1,2 or 3

  2. i循环遍历所有段

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

  3. 最里面j loop

    只是步距角,如果不改变步距的方向及其大小,看看段是否更接近所需的尺寸10递归层数越多,精度越高j越精确

  4. 在......的最后k/kd loop

    角度应该是2*PI所以如果它或多或少则重新调整l0相应地,但为了避免振荡,也使用原始平均值l0 size

就这些

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

查找椭圆或贝塞尔曲线上的等距点 的相关文章

  • 如何在Python的SciPy中更改稀疏矩阵中的元素?

    我构建了一个小代码 我想用它来解决涉及大型稀疏矩阵的特征值问题 它工作正常 我现在要做的就是将稀疏矩阵中的一些元素设置为零 即最顶行中的元素 对应于实现边界条件 我可以调整下面的列向量 C0 C1 和 C2 来实现这一点 不过我想知道是否有
  • jQuery 中的 Javascript .files[0] 属性

    jQuery 中是否有与此语句等效的语句 var value document getElementById id files 0 使用附加 files 0 的标准 jQuery 选择器似乎不起作用 并且我找不到与 files 等效的 jQ
  • 从 x,y 屏幕空间坐标查找 2D 等距网格上的列、行(将方程转换为函数)

    我试图在屏幕空间点 x y 的二维等距网格中找到行 列 现在我几乎知道我需要做什么 即找到上图中红色向量的长度 然后将其与表示网格边界的向量的长度 由黑色向量表示 进行比较 现在我在数学堆栈交换中寻求帮助 以获得用于计算点 x y 与黑色边
  • 计算Javascript中两次点击之间的时间

    我想用 javascript 计算属性的两次点击之间的时间 但我不知道如何 例如 a href click here a 如果用户单击多次 假设 5 秒内 我想显示警报 如果有帮助的话我正在使用 jQuery 我对 javascript 不
  • 禁用 JavaScript 中的右键单击

    当我尝试禁用右键单击时 它不起作用 我尝试使用下面的代码 document onclick function e console log e button if e button 2 e preventDefault return fals
  • Ember.JS - 如何在同一页面中使用多个模型、控制器和视图?

    我主要了解 Ember JS 的基础知识 大多数示例实际上只处理单个控制器和模型以在页面上显示某些内容 我真的很想用 Ember 构建一个完整的 Web 应用程序 所以有人能告诉我如何组织和连接多个控制器 模型和视图到一个页面中吗 例如 如
  • 如何使用 jQuery 向表中添加新行,并为其分配递增的 id

    我有一个现有的 HTML 表格 它是用户输入 GPS 点的表单的一部分 用户还可以选择上传 GPS 数据点 我想要一个用户可以按下的按钮 其中一些 Javascript 会向表中添加一个或多个新行 但新行必须继续增加表中使用的名称和 id
  • JavaScript 动画平滑滚动

    默认情况下 当您有这样的片段链接时 a href some url some fragment some text a 浏览器立即向下滚动到该片段 我该如何编程才能使用标准 JS 顺利地向下移动到该片段 这是一个例子 Example htt
  • 如何改变HTML5视频的播放速度?

    如何更改 HTML5 中的视频播放速度 我查过视频标签的属性 https www w3schools com html html5 video asp在 w3school 但无法做到这一点 根据这个网站 http www chipwreck
  • 使react-leaflet能够离线使用

    我一直在使用反应传单 https github com PaulLeCam react leaflet图书馆 到目前为止运作良好 现在我希望网站预加载尽可能多的图块 以便网络应用程序 也是 PWA 可以在没有互联网的情况下使用 我找到了一些
  • java数学中的组合“N选择R”?

    java库中是否有内置方法可以为任何N R计算 N选择R 公式 实际上很容易计算N choose K甚至不需要计算阶乘 我们知道 公式为 N choose K is N N K K 因此 公式为 N choose K 1 is N N N
  • 使水平滚动条始终可见,即使底部不在视图中

    我将用一个片段来开始这个问题 该片段几乎显示了我想要完成的任务 wrapper overflow hidden display flex sidebar min width 200px background 333 color FFF co
  • WebRTC:通道、轨道和流与 RTP SSRC 和 RTP 会话之间的关系

    来自 Mozilla 网站 https developer mozilla org en US docs Web API Media Streams API https developer mozilla org en US docs We
  • 从多维无穷大数组中删除数组元素

    我想删除一个特定元素 例如 我想删除元素id 76在下面的数组中 而且 数组可以无限地组合在一起 这里的问题是我无法刷新页面 因为我使用 Vue js 进行即时操作 如果我能做到这一点 我的下一个问题可能是如何在我现在想要的地方添加一个元素
  • 您如何看待引导模式触发器的相应回调?

    On 引导模态 http getbootstrap com javascript modals 我们知道我们可以为触发器绑定事件 例如show or hide using show shown hide hidden 但此事件绑定仅适用于一
  • Restangular - _.contains() 不是一个函数

    如果您最近通过 Bower 更新了 Restangular 它将安装最新的 Lodash 新的 4 0 然而 这是一个问题 因为 Restangular Angular 现在会抛出错误 contains 不是函数 你怎么解决 解决方案非常简
  • 我可以使用 jQuery 动态创建文件(及其内容)吗? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 这是我的 HTML 代码 ul li
  • 在矩阵/位图中查找质量簇

    这是此处发布的问题的延续 在 2D 位图上查找质心 https stackoverflow com questions 408358 finding the center of mass on a 2d bitmap正如给出的例子 它讨论了
  • Bootstrap 3 / 显示模式不适用于 javascript 方式

    我用Modal http getbootstrap com javascript modalsBootstrap 3 0 的功能 我有这个代码 a href myNestedContent Open the modal containing
  • 在 javascript 中使用 xPath 解析具有默认命名空间的 XML

    我需要创建一个 XML xPath 解析器 所有解析都必须在客户端进行 使用 JavaScript 我创建了一个 javascript 来执行此操作 在默认名称空间发挥作用之前 一切看起来都正常 我根本无法查询具有默认命名空间的 XML 我

随机推荐