如何移动循环路径中的第一个点?

如何移动循环路径中的第一个点?

给定一个循环的指南(或路径)g,我想构造一个相同的指南,但所有控制点的n位置都发生了偏移。结果是第一个节点和最后一个节点发生了偏移,例如,如果 a、b、c 和 d 是从 a 开始的循环路径的节点,则偏移后n=2得到的路径应为 c、d、a、b,从 c 开始。

我尝试从指南中提取控制点和张力参数,但似乎无法在我构建的指南中设置这些字段。这是我尝试过的:

guide rotate_seam(guide g, int n)
{
    guide res;
    tensionSpecifier T[], t;
    pair[] P;
    T.cyclic = true;
    P.cyclic = true;
    for (int i = 0; i < length(g); ++i)
    {
        t = tensionSpecifier(g, i);
        P.push(point(g, i));
        T.push(t);
    }
    T = T[n:n+T.length];
    P = P[n:n+P.length];
    for (pair i : P) { res = res..i; }
    res = res..cycle;
    for (int i = 0; i < T.length; ++i)
    {
        t = tensionSpecifier(res, i);
        t.in = T[i].in;
        t.out = T[i].out;
        t.atLeast = T[i].atLeast;
    }
    return res;
}

答案1

这是一个相当简短的解决方案:

path rotate_seam(path g, int n) {
  // Ensure path is cyclic so that `subpath` can extend past the end of the path.
  if (!cyclic(g)) g = g & cycle;
  return subpath(g, n, length(g) + n) & cycle;
}

请注意,& cycle丢弃路径中的最后一个节点,并将第一个节点放置在其位置,如果最后一个节点实际上与第一个节点是同一点,那么这是正确的做法。

答案2

我找到了解决方案。新指南是使用控制点信息逐段构建的。据我所知,没有办法传递任何包含控制点的结构并让 Asymptote 按照规范构建指南。

struct CPoint
{
    pair ctrl;
    pair pre_ctrl;
    pair post_ctrl;
}

guide rotate_seam(path p, int n)
{
    CPoint P[];
    P.cyclic = true;
    for (int i = 0; i < length(p); ++i)
    {
        CPoint tmp;
        tmp.ctrl = point(p, i);
        tmp.pre_ctrl = precontrol(p, i);
        tmp.post_ctrl = postcontrol(p, i);
        P.push(tmp);
    }
    P = P[n:n+P.length];
    guide res, seg;
    for (int i = 0; i < P.length - 1; ++i)
    {
        seg = P[i].ctrl..controls P[i].post_ctrl and P[i + 1].pre_ctrl..P[i + 1].ctrl;
        res = res & seg;
    }
    seg = P[P.length - 1].ctrl..controls P[P.length - 1].post_ctrl and P[0].pre_ctrl..P[0].ctrl;
    res = res & seg;
    return res & cycle;
}

相关内容