早上好!几天来,我一直以 MP-Newbie 的身份尝试在我的图 p 和红色水平线之间找到正确的交点。
我的例子中的点位于左下角的红色三角形。
我的图表 p 中的数据位于data.txt
一个名为“通过图表包例程调用”的外部文件中。
我的实际代码是:
\documentclass{article}
\usepackage{luamplib}
\usepackage{xcolor}
\begin{document}
\pagenumbering{gobble}
\begin{mplibcode}
prologues := 3;
defaultfont := "phvr8r";
defaultfontscale := 0.92*8pt/fontsize defaultfont;
input graph;
Gtemplate.itick:=origin--(4bp,0);
Gtemplate.otick:=(-4bp,0)--origin;
beginfig(1)
draw begingraph(100bp*u,100bp*u);
path p, q; % p ... curve, q ... red line
pair n; % n ... should be the intersection point -> gives error during compilation
u = 3;
% Data from data.txt - the six pts are as black points on the curve p.
p:=(1,1){right}
gdata("data.txt",$, ..(scantokens $1, scantokens $2));
gdraw p
plot btex \raisebox{-0.5\height}{\makebox[0pt] {$\bullet$}} etex
withpen pencircle scaled 1bp;
% Grid vertikal
autogrid(,);
for x=0 step 10 until 100:
grid.bot (format("%0f", x),x) withpen pencircle scaled 0.22bp withcolor 0.6 white;
endfor
% Grid horizontal
autogrid(,);
for y=0 step 10 until 100:
grid.lft (format("%0f ", y),y) withpen pencircle scaled 0.22bp withcolor 0.6 white;
endfor
setrange(-3,-3,103,103);
% upper red line
z1 = (0,87.5*u); z2= (100*u,87.5*u);
q = z1 -- z2;
draw q withcolor red;
%n = p intersectionpoint q; % gives the error when uncommented
% define the intersection point of the curve with the red line - it actually gives the red triangle at origin in my graph.
label.bot(btex $\color{red}\triangle$ etex,
(z1 -- z2) intersectiontimes p);
endgraph;
endfig;
end
\end{mplibcode}
\end{document}
我的文件data.txt
包含以下几点(它们在一行中写成两个数字,只有空格和 CR,双斜线是为了更好的可读性):
1 1 // 5 2 // 22 30 // 26.5 50 // 45 80 // 62 90 // 98 99
任何帮助或提示都将不胜感激。提前谢谢您。
答案1
我认为我会让它更简单一点——图库有一些有用的功能,但它增加了一个更复杂的界面。你可以用普通的 MP 更简单地为该特定图表做你想做的一切。而且你有更多的控制权……
这是用普通 MP 绘制的版本(并且红线移动到了 87 而不是 90,以显示它可以在任何地方工作)。
我添加了解释每个部分的评论。
\documentclass[border=5mm]{standalone}
\usepackage{luatex85}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);
% define the unit size
numeric u;
u = 1mm;
% define the axes first
path xx, yy;
xx = (3 left -- 103 right) scaled u;
yy = xx rotated 90;
% now the two lines to mark
path p, q;
p = ((1, 1) .. (5,2) .. (22,30) .. (26.5,50) .. (45,80) .. (62,90) .. (98,99)) scaled u;
q = xx shifted (0, 87u);
% and a triangular marker
path t;
t = (for i=0 upto 2: up rotated 120i -- endfor cycle) scaled u;
% draw and label the grid
for i=0 step 10 until 100:
draw xx shifted(0, i*u) withcolor 3/4 white;
draw yy shifted(i*u, 0) withcolor 3/4 white;
label.lft("$" & decimal i & "$", point 0 of xx shifted (0, i*u));
label.bot("$" & decimal i & "$", point 0 of yy shifted (i*u, 0));
endfor
% and a box round it
draw unitsquare scaled arclength(xx)
shifted (xpart point 0 of xx, ypart point 0 of yy);
% now draw the two lines
draw q withcolor 2/3 red;
draw p;
% mark all the points along p
for i=0 upto length p:
drawdot point i of p withpen pencircle scaled dotlabeldiam;
endfor
% add the marker in red
draw t shifted (p intersectionpoint q)
shifted 8 down
withcolor 2/3 red;
endfig;
\end{mplibcode}
\end{document}
答案2
您需要使用intersectionpoint
来获取交叉点,intersectiontimes
仅返回两条路径到达该点的“时间”。例如,如果两条路径都从同一点开始,intersectiontimes
则将返回,(0,0)
因为交叉点位于开始处,时间0
。如果它位于 的开始处p
和 的第二个控制点q
,p intersectiontimes q
则将返回(0,1)
。
当然,这些对并不代表坐标,绘制它们会导致在原点附近出现一些点。
代码已经提到,intersectionpoint
但说它“给出错误”。有问题的错误是
! The paths don't intersect.
如果 MetaPost 认为路径不相交,它如何计算intersectiontimes
?intersectiontimes
两个不相交路径的是根据定义(使用不是有效时间(-1, -1)
的事实),因此不会引发错误,而是返回一个标记。-1
intersectiontimes
但为什么这些路径不相交呢?根据 MetaPost 的说法,这些路径是
>> Path at line 43:
(1,1)..controls (1,1) and (1,1)
..(1,1)..controls (2.36905,1.16934) and (3.71233,1.50516)
..(5,2)..controls (15.8229,6.15913) and (19.67946,18.41534)
..(22,30)..controls (23.3429,36.70403) and (24.53044,43.45076)
..(26.5,50)..controls (29.95534,61.48978) and (35.82167,72.26625)
..(45,80)..controls (50.05702,84.2611) and (55.92546,87.39604)
..(62,90)..controls (73.44186,94.90475) and (85.59612,97.94331)
..(98,99)
>> Path at line 44:
(0,262.5)..controls (100,262.5) and (200,262.5)
..(300,262.5)
可以看到,y
第一个图的值从未超过100
,但y
第二个图的值是262.5
。它们在图中仍然相交,因为它们在不同的坐标系中给出:
第一个图形的值来自 ,它data.txt
精确地包含文件中的坐标,然后由 绘制,gdraw
将其转换为输出中的实际尺寸。第二个路径直接在输出坐标中给出((隐式)单位为bp
),并由 绘制draw
,默认情况下不应用进一步的转换。
因此路径不相交,但输出中的变换路径相交。
我们如何解决这个问题?最简单的方法是将q
(红线)更改为使用图形坐标,然后使用gdraw/glabel
:draw/label
替换
z1 = (0,87.5*u); z2= (100*u,87.5*u);
q = z1 -- z2;
draw q withcolor red;
%n = p intersectionpoint q; % gives the error when uncommented
% define the intersection point of the curve with the red line - it actually gives the red triangle at origin in my graph.
label.bot(btex $\color{red}\triangle$ etex,
(z1 -- z2) intersectiontimes p);
和
z1 = (-3,90); z2= (103,90);
q = z1 -- z2;
gdraw q withcolor red;
n = p intersectionpoint q;
% define the intersection point of the curve with the red line
glabel.bot(btex $\color{red}\triangle$ etex, n);