延长一条线来查找路径上的交叉时间

延长一条线来查找路径上的交叉时间

我正在写 metapost。我在两点(z0 和 z1)之间有一条曲线,在附近的某个任意点(z2)。

我将 z2 反射到直线上,z0--z1得到它的对立面 z3。我希望延伸这条线z2--z3,使它与曲线相交,这样我就能找到那个交点。

我认为我可以使用类似unitvector(direction 0 of (z0 -- z1))乘以whatever长度的方法,通过 metapost 求解以在point whatever曲线处相交。但我不确定如何在 metapost 中表达这一点。

谢谢

在此处输入图片描述

beginfig(1)

    u := 1cm;

    z0 = (1u, 2u);
    z1 = (4u, 3u);

    % some curve which does not cross z0--z1
    draw z0{up} .. z1{down};

    % an arbitary point
    z2 = (2u, 3u);
    z3 = z2 reflectedabout(z0, z1);

    draw z0 -- z1 dashed evenly;
    draw z2 -- z3 withcolor red;

    draw z0 withpen pencircle scaled 3bp;
    draw z1 withpen pencircle scaled 3bp;
    draw z2 withpen pencircle scaled 3bp withcolor red;
    draw z3 withpen pencircle scaled 3bp withcolor red;

    label.bot(btex $z_0$ etex, z0);
    label.bot(btex $z_1$ etex, z1);
    label.top(btex $z_2$ etex, z2);
    label.bot(btex $z_3$ etex, z3);

endfig;

end.

答案1

您可以使用solve宏来解决此类问题。

如果能写出这样的内容就好了:

path a;  a = z0{up} .. z1{down};
z4 = whatever[z2,z3] = point whatever of a;

但如果你这样做,MP 会抱怨它无法处理point (unknown) of known path。所以你需要使用solve。这个想法是你编写一个宏,给出一个真值或一个假值,然后将其提供给solve。然后 MP 会在“真值和假值之间的临界点”找到该值。这在Metafont 书籍,第 176-177 页。

这是我针对您的问题所做的尝试。

beginfig(1)

    u := 1cm;

    z0 = (1u, 2u);
    z1 = (4u, 3u);

    % some curve which does not cross z0--z1
    path a;
    a = z0{up} .. z1{down};
    draw a;

    % an arbitary point
    z2 = (2u, 3u);
    z3 = z2 reflectedabout(z0, z1);

    vardef inline(expr t) = 
       angle unitvector(point t of a - z2) > 
       angle unitvector(point t of a - z3)
    enddef;

    z4 = point solve inline(0,1) of a;

    draw z0 -- z1 dashed evenly;
    draw z2 -- z3 withcolor red;

    draw z0 withpen pencircle scaled 3bp;
    draw z1 withpen pencircle scaled 3bp;
    draw z2 withpen pencircle scaled 3bp withcolor red;
    draw z3 withpen pencircle scaled 3bp withcolor red;
    draw z4 withpen pencircle scaled 3bp withcolor blue;

    label.bot(btex $z_0$ etex, z0);
    label.bot(btex $z_1$ etex, z1);
    label.top(btex $z_2$ etex, z2);
    label.bot(btex $z_3$ etex, z3);
    label.ulft(btex $z_4$ etex, z4);

endfig;

end.

结果是:

在此处输入图片描述

请注意,这将适用于任意曲线路径a。唯一的要求是宏应返回true第一个参数和false第二个参数。因此,如果路径沿相反方向运行,则必须将更改为><使用来调用它以inline(1,0)反转真/假值。

答案2

延伸线段z3--z2并计算与intersectionpoint

beginfig(1)

    u := 1cm;

    z0 = (1u, 2u);
    z1 = (4u, 3u);

    % some curve which does not cross z0--z1
    path p,q;
    p =  z0{up} .. z1{down};
    draw p;

    % an arbitary point
    z2 = (2u, 3u);
    z3 = z2 reflectedabout(z0, z1);

    z5 = z3 + 100(z2 - z3);
    q = z3 -- z5;

    z4 = p intersectionpoint q;

    draw z0 -- z1 dashed evenly;
    draw z3 -- z4 withcolor red;

    draw z0 withpen pencircle scaled 3bp;
    draw z1 withpen pencircle scaled 3bp;
    draw z2 withpen pencircle scaled 3bp withcolor red;
    draw z3 withpen pencircle scaled 3bp withcolor red;
    draw z4 withpen pencircle scaled 3bp withcolor red;

    label.bot(btex $z_0$ etex, z0);
    label.bot(btex $z_1$ etex, z1);
    label.rt(btex $z_2$ etex, z2);
    label.bot(btex $z_3$ etex, z3);
    label.top(btex $z_4$ etex, z4);

endfig;

end.

在此处输入图片描述

如果您不想对乘数进行硬编码,则可以使用较慢的例程,重新计算线段的延伸,直到它与圆弧相交。

beginfig(1)

    u := 1cm;

    z0 = (1u, 2u);
    z1 = (4u, 3u);

    % some curve which does not cross z0--z1
    path p,q;
    p =  z0{up} .. z1{down};
    draw p;

    % an arbitary point
    z2 = (2u, 3u);
    z3 = z2 reflectedabout(z0, z1);

    n = 0;
    forever:
      n := n+1;
      x5 := x3 + n*(x2 - x3);
      x6 := x3 - n*(x2 - x3);
      y5 := y3 + n*(y2 - y3);
      y6 := y3 - n*(y2 - y3);
      q := z5 -- z6;
      exitif xpart(p intersectiontimes q) > 0;
    endfor

    z4 = p intersectionpoint q;

    draw z0 -- z1 dashed evenly;
    draw z3 -- z4 withcolor red;

    draw z0 withpen pencircle scaled 3bp;
    draw z1 withpen pencircle scaled 3bp;
    draw z2 withpen pencircle scaled 3bp withcolor red;
    draw z3 withpen pencircle scaled 3bp withcolor red;
    draw z4 withpen pencircle scaled 3bp withcolor red;

    label.bot(btex $z_0$ etex, z0);
    label.bot(btex $z_1$ etex, z1);
    label.rt(btex $z_2$ etex, z2);
    label.bot(btex $z_3$ etex, z3);
    label.top(btex $z_4$ etex, z4);

endfig;

end.

如果线实际上与圆弧不相交,您可能还需要检查搜索限制。

相关内容