Можно ли нарисовать путь из списка или иным образом избежать кусочно-совместных объявлений? (В metapost)

Можно ли нарисовать путь из списка или иным образом избежать кусочно-совместных объявлений? (В metapost)

Допустим, у меня есть математическая функция f, которую я хочу построить.

Самый простой способ построить график — оценить его небольшими шагами вдоль области построения и сгенерировать точки.

например f(0); f(0.1); f(0.2) ... преобразуются в (0, f(0)); (0.1, f(0.1)); (0.2, f(0.2)) ...

Если вы хотите нарисовать кривую, а не точки, вы можете сделать следующее:

draw (0, f(0))--(0.1, f(0.1)); 
draw (0.1, f(0.1))--(0.2, f(0.2));

Внутри цикла. Другими словами, вы пишете цикл, сохраняете результат предыдущего вычисления, вычисляете текущее значение x, рисуете прямой отрезок, обновляете x и продолжаете.

Возможно ли сделать, например:

%psuedocode
pair list[];
draw list;

?

решение1

Вот одна из возможностей с metapost. Чтобы макрос мог принять массив в качестве аргумента, он объявляется как suffixаргумент, т. е. тот, который имеет суффиксы, в данном случае 0,1,2,.... Входной массив должен начинаться с индекса/суффикса 0.

\documentclass[border=10cm]{standalone}
\usepackage{luamplib}

\begin{document}
\begin{mplibcode}
vardef pairs(suffix P)=
    save p_,i_; path p_;
    i_:=0;
    p_:=P[0] forever: exitif not (known P[incr i_]); --P[i_] endfor;
    p_
enddef;

beginfig(0);
u:=1cm;
pair p[];
p[0]=origin;
p[1]=u*(1,1);
p[2]=u*(2,0);
p[3]=u*(4,0);

draw pairs(p) withpen pencircle scaled 1bp withcolor red;
endfig;
\end{mplibcode}

\end{document}

введите описание изображения здесь

Редактировать: Согласно предложению Трастона, здесь мы можем быть немного более общими. Если вам нужен вариант с прямыми сегментами или кривыми Безье, то вы можете использовать:

\begin{mplibcode}
vardef pairs(suffix P)(text joiner)=
    save p_,i_; path p_;
    i_:=0;
    P[0] forever: exitif not (known P[incr i_]); joiner P[i_] endfor
enddef;

beginfig(0);
u:=1cm;
pair p[];
p[0]=origin;
p[1]=u*(1,1);
p[2]=u*(2,0);
p[3]=u*(4,-1);
drawoptions(withpen pencircle scaled 1bp);
draw pairs(p,..) withcolor red;
draw pairs(p,--) withcolor blue;
draw pairs(p,{right}..{right});
%k:=0;
%draw pairs(p,{dir (incr k*30)}..{right}) withcolor green;
drawoptions();

endfig;
\end{mplibcode}

введите описание изображения здесь

решение2

Так как многие ТикZ ответы получают ответы MetaPost (что, конечно, здорово) вот TiкZ ответ на этот предположительно вопрос MetaPost. Если, скажем, имеется список, \def\mylist{(0,1) (1,2) (2.5,1/2)}то очень хорошо известно, что вы можете построить этот список с помощью \draw[blue] plot[smooth] coordinates {\mylist};. Менее известно, что вы также можете построить списки, которые имеют структуру массива Mathematica/C++, скажем, \def\mylist{{0,1},{1,2},{2.5,1/2}}. Это работает, эксплуатируя то, что TiкZ может анализировать и получать доступ к массивам,

\draw plot[samples at={0,1,2}] ({{\mylist}[\x][0]},{{\mylist}[\x][1]});

Полная версия MWE с примерами плавности:

\documentclass[tikz,margin=3]{standalone}
\begin{document}
\begin{tikzpicture}
\def\mylist{(0,1) (1,2) (2.5,1/2)}
\draw plot coordinates {\mylist};
\draw[blue] plot[smooth] coordinates {\mylist};
\begin{scope}[yshift=-4cm]
\def\mylist{{0,1},{1,2},{2.5,1/2}}
\draw plot[samples at={0,1,2}] ({{\mylist}[\x][0]},{{\mylist}[\x][1]});
\draw[blue] plot[smooth,samples at={0,1,2}] ({{\mylist}[\x][0]},{{\mylist}[\x][1]});
\end{scope}
\end{tikzpicture}
\end{document}

введите описание изображения здесь

Связанный контент