我正在写 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.
如果线实际上与圆弧不相交,您可能还需要检查搜索限制。