如何测试两个数的乘积是否为正数以及找到它们的绝对值?

如何测试两个数的乘积是否为正数以及找到它们的绝对值?

我正在尝试使用一些乳胶编码来简化我的工作,目的是根据输入生成两种类型的图表。第一种是线条只向上的图表

在此处输入图片描述

第二个是允许线条像这样返回(用 PowerPoint 绘制):

在此处输入图片描述

我已经有了第一类图表的工作代码这里其中图表顶部和底部的点从左到右按 1 到 n 进行编号。下面是代码的 MWE。

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}
\tikzset{pics/planar/.style 2 args = {
    code = {
      \draw[color=red] (0,0) rectangle (#1*0.3+0.3,0.7);
      \foreach \dot in {1,...,#1}{ % draw the dots
          \filldraw (0.3*\dot,0) circle [radius=1pt];
          \filldraw (0.3*\dot,0.7) circle [radius=1pt];
      }
      % draw the lines
      \foreach \x/\y in #2
        \draw[->,>=stealth](0.3*\x,0) .. controls +(0,0.2) and +(0,-0.2) .. (0.3*\y,0.7);
    }
  }
}

\usepackage{xparse}
\NewDocumentCommand\PlanarDiagram{ O{} D(){3} m }{%
   \begin{tikzpicture}[#1]
     \foreach \diag [count=\c] in {#3} {
       \draw(0,\c*0.7) pic[#1]{planar={#2}{\diag}};
     }
  \end{tikzpicture}%
}

\begin{document}

   \PlanarDiagram(5){{1/2}}                  \quad
   \PlanarDiagram{{1/2,2/2}, {2/3,3/1}}      \quad
   \PlanarDiagram(4){{1/2, 3/1, 3/3}, {1/1, 2/3, 3/3}}

   \PlanarDiagram[scale=0.7, draw=blue](4){{1/2, 3/1, 3/3}, {1/1, 2/3, 3/3}}

\end{document}

我希望如果我将顶部的点从 1 正数编号到 n,将底部的点从 -1 负数编号到 -n,我可以通过命令的输入将两种类型的线分开,因此命令可以是这样的

\NewPlanarDiagram{{-1/-4,-2/-3,1/2,3/4}} % diagram on the left
\NewPlanarDiagram{{-1/3,-2/-3,1/2,4/4}} % diagram on the right

我可以对 for 循环中的宏做类似的事情

\foreach \x/\y in #2
                \ifnum \x < 0 
                    \let \signx=-1 
                \else 
                    \let \signx=1 
                \fi
                \ifnum \y < 0 
                    \let \signy=-1 
                \else 
                    \let \signy=1 
                \fi
                \let \xysign= \multiply\signx by \signy
                \ifnum\xysign<0
                    \draw(0.3*\x,0.35+\signx*0.35) .. controls +(0,0.2) and +(0,-0.2) .. (0.3*\y,0.35+\signy*0.35);
                \else
                    \draw(0.3*\x,0.35+\signx*0.35) .. controls +(0,0.2) and +(0,-0.2) .. (0.3*\y,0.35+\signy*0.35);
                \fi

但出现了许多错误消息。有什么想法吗?

答案1

我只想使用一个pic,然后以原始用法仍然有效的方式对其进行升级。从技术方面来说,你可以引入一个测试整数

\pgfmathtruncatemacro{\itest}{(\XX<0)+2*(\YY<0)}

\YY它将根据两个符号都是正数、只有 的符号为正数、只有 的符号为正数或两个符号都是负数分别取值为 0、1、2 或 3。\XX然后,您可以使用简单的\ifcase

\documentclass{article}
\usepackage{tikz}
\newif\ifPlanarDiagamShowLabels
\usetikzlibrary{arrows.meta,bending}
\tikzset{pics/planar diagram/.style={code={
            \tikzset{planar diagram/.cd,#1}%
            \def\pv##1{\pgfkeysvalueof{/tikz/planar diagram/##1}}%
            \draw[/tikz/planar diagram/frame] ({-(\pv{n}+1)*\pv{x}/2},-\pv{y}/2) rectangle 
                ({(\pv{n}+1))*\pv{x}/2},\pv{y}/2);
            \ifPlanarDiagamShowLabels
              \path foreach \XX in {1,...,\pv{n}}
              {({-(\pv{n}+1)*\pv{x}/2+\XX*\pv{x}},-\pv{y}/2)
                   node[circle,fill,inner sep=1pt,label=below:$\XX$] (-b-\XX){}
               ({-(\pv{n}+1)*\pv{x}/2+\XX*\pv{x}},\pv{y}/2)
                   node[circle,fill,inner sep=1pt,label=above:$\XX$] (-t-\XX){}};
            \else
              \path foreach \XX in {1,...,\pv{n}}
              {({-(\pv{n}+1)*\pv{x}/2+\XX*\pv{x}},-\pv{y}/2)
                   node[circle,fill,inner sep=1pt] (-b-\XX){}
               ({-(\pv{n}+1)*\pv{x}/2+\XX*\pv{x}},\pv{y}/2)
                   node[circle,fill,inner sep=1pt] (-t-\XX){}};
            \fi
            \edef\localconnections{\pv{connections}}
             \foreach \XX/\YY in \localconnections{%
             \ifnum\XX=\YY
              \typeout{Loops are not implemented (yet).}
             \else 
              \pgfmathtruncatemacro{\itest}{(\XX<0)+2*(\YY<0)}
              \ifcase\itest % both >0
               \draw[planar diagram/arrow] (-t-\XX) to[out=-90,in=-90] (-t-\YY);
              \or % \YY >0
               \draw[planar diagram/arrow] (-b\XX) to[out=90,in=-90] (-t-\YY);
              \or % \XX >0
               \draw[planar diagram/arrow] (-t-\XX) to[out=-90,in=90] (-b\YY);
              \or % both <0
               \draw[planar diagram/arrow] (-b\XX) to[out=90,in=90] (-b\YY);
              \fi
             \fi
            }
    }},planar diagram/.cd,n/.initial=5,x/.initial=0.3,y/.initial=0.7,
    show labels/.is if=PlanarDiagamShowLabels,frame/.style={},
    connections/.initial={1/1},arrow/.style={-{Stealth[bend]}}
}

\begin{document}
\begin{tikzpicture}
 \path (0,0) pic[scale=2]{planar diagram={n=4,
 arrow/.style={thick,cyan},frame/.style={draw=red},
 connections={-1/-4,-2/-3,1/2,3/4}}}
 (5,0)  pic[scale=2]{planar diagram={n=4,arrow/.style={thick,cyan},
 connections={-1/3,-2/-3,1/2,-4/4}}}
 (0,-3) pic[scale=2]{planar diagram={n=5,
 connections={-1/3,-2/4,-3/1,-4/2,-5/5}}};
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

建议的循环中的主要问题是\let不能以这种方式工作:右侧必须是单个标记。您可以使用\def\pgfmathsetmacro。第二个问题:您的两个替代代码路径是相同的。本着与您编写的相同精​​神,我将在循环中使用类似以下内容:

\foreach \x/\y in #2 {
  \pgfmathtruncatemacro{\signx}{\x < 0 ? -1 : 1}
  \pgfmathtruncatemacro{\signy}{\y < 0 ? -1 : 1}
  \pgfmathsetmacro{\myFactor}
    {(1+0.2*(1+\signx*\signy)*abs(abs(\x)-abs(\y)))}
  \draw
    ({0.3*abs(\x)}, 0.35+\signx*0.35)
    .. controls +(0, -\myFactor*\signx*0.2) and
                +(0, -\myFactor*\signy*0.2) ..
    ({0.3*abs(\y)}, 0.35+\signy*0.35);
}

我还重写了您的\PlanarDiagram宏,\NewPlanarDiagram使用了更多expl3内容,但最终没有必要(如果您感兴趣,请查看答案的历史记录)。#1不过,我注释掉了一个,因为您将它同时传递给了tikzpicture和。此外,您在第二个提议的图表中pic写了4/4而不是。在我的示例中,宏的调用方式如下:-4/4\NewPlanarDiagram

\NewPlanarDiagram(4){{-1/-4,-2/-3,1/2,3/4}, {-1/3,-2/-3,1/2,-4/4}}

完整示例:

\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}

\tikzset{pics/planar/.style 2 args = {
    code = {
      \draw[color=red] (0,0) rectangle (#1*0.3+0.3,0.7);
      \foreach \dot in {1,...,#1} { % draw the dots
          \filldraw (0.3*\dot,0) circle [radius=1pt];
          \filldraw (0.3*\dot,0.7) circle [radius=1pt];
      }
      % draw the lines
      \foreach \x/\y in #2 {
        \pgfmathtruncatemacro{\signx}{\x < 0 ? -1 : 1}
        \pgfmathtruncatemacro{\signy}{\y < 0 ? -1 : 1}
        \pgfmathsetmacro{\myFactor}
          {(1+0.2*(1+\signx*\signy)*abs(abs(\x)-abs(\y)))}
        \draw
          ({0.3*abs(\x)}, 0.35+\signx*0.35)
          .. controls +(0, -\myFactor*\signx*0.2) and
                      +(0, -\myFactor*\signy*0.2) ..
          ({0.3*abs(\y)}, 0.35+\signy*0.35);
      }
    }
  }
}

\NewDocumentCommand \NewPlanarDiagram { O{} D(){3} m }
  {%
      \begin{tikzpicture}%[#1] commented out: already passed to the pic...
        \foreach \diag [count=\c] in {#3} {
          \draw(0, -\c*0.9) pic[#1] {planar={#2}{\diag}};
        }
     \end{tikzpicture}%
  }

\begin{document}

\NewPlanarDiagram(4){{-1/-4,-2/-3,1/2,3/4}, {-1/3,-2/-3,1/2,-4/4}}

\end{document}

在此处输入图片描述

答案3

为了保持连续性,这里是我对您之前问题的回答的更新,其中添加了一些“如果/那么”来处理新的情况。

在此处输入图片描述

编译lualatex

\documentclass{article}
\usepackage{luamplib}
\mplibforcehmode
\begin{document}
\begin{mplibcode}
ux:=1cm; % horizontal scale
uy:=2cm; % vertical scale
ds:=.15*ux; % dot size

def planar(expr pts,levels)(text connections)=
    clearxy; save k,l,n;
    x=(pts+1)*ux; y=levels*uy; % max x, max y
    for i=0 upto levels:
        draw (origin--(x,0)) shifted (0,i*uy) withcolor red; % draw horizontal bars
        for j=1 upto pts: drawdot (j*ux,i*uy) withpen pencircle scaled ds; endfor; % draw dots
    endfor;
    draw origin--(0,y) withcolor red; % draw left vertical bar
    draw (x,0)--(x,y) withcolor red; % draw right vertical bar
    l=length(connections); n=k=0;
    for i=0 upto l:
        if (substring(i,i+1) of connections="|") or (i=l): % find separators
            for p=scantokens(substring(k,i) of connections): % iterate through list up to separator
                if (xpart p<0) and (ypart p>0): % between levels
                    drawarrow (abs(xpart p)*ux,n*uy){up}..{up}((ypart p)*ux,(n+1)*uy) 
                          cutafter fullcircle scaled (ds+1) shifted ((ypart p)*ux,(n+1)*uy);
                elseif (xpart p<0) and (ypart p<0): % bottom level
                    draw (abs(xpart p)*ux,n*uy){up}..{down}(abs(ypart p)*ux,n*uy) ;
                elseif (xpart p>0) and (ypart p>0): % top level
                    draw (abs(xpart p)*ux,(n+1)*uy){down}..{up}(abs(ypart p)*ux,(n+1)*uy);
                fi;
            endfor;
        k:=i+1; % pickup after separator
        n:=n+1; % increase level
        fi;
    endfor;
enddef;

beginfig(0);
    planar(3,3)("(-1,-2),(-2,3),(1,2)|(-1,3),(-3,-2)|(-1,-2),(-1,-3),(-1,1)");
endfig;
\end{mplibcode}
\end{document}

答案4

我对薛定谔猫的答案做了一些修改,让圆圈看起来更漂亮,最后还是用了它。我会把它贴在这里,以防有人偶然发现它。

\usepackage{tikz}
\usetikzlibrary{braids,backgrounds,arrows.meta,fit}

\tikzset{pics/planar diagram/.style={code={
            \tikzset{planar diagram/.cd,#1}%
            \def\pv##1{\pgfkeysvalueof{/tikz/planar diagram/##1}}%
                \draw[/tikz/planar diagram/frame] ({-(\pv{n}+1)*\pv{x}/2},-\pv{y}/2) rectangle ({(\pv{n}+1))*\pv{x}/2},\pv{y}/2);
                \path foreach \XX in {1,...,\pv{n}}
                {({-(\pv{n}+1)*\pv{x}/2+\XX*\pv{x}},-\pv{y}/2)
                    node[circle,fill,inner sep=0.7pt] (-b-\XX){}
                    ({-(\pv{n}+1)*\pv{x}/2+\XX*\pv{x}},\pv{y}/2)
                    node[circle,fill,inner sep=0.7pt] (-t-\XX){}};
            \edef
            \localconnections{\pv{connections}}
            \foreach \XX/\YY in \localconnections{%
                \ifnum\XX=\YY
                \typeout{Loops are not implemented (yet).}
                \else 
                \pgfmathtruncatemacro{\itest}{(\XX<0)+2*(\YY<0)}
                \ifcase\itest % both >0
                \draw[planar diagram/arrow] (-t-\XX) .. controls +(0,-0.2*\pv{y}+0.025*\XX/\pv{x}-0.025*\YY/\pv{x}) and +(0,-0.2*\pv{y}+0.025*\XX/\pv{x}-0.025*\YY/\pv{x}) .. (-t-\YY);
                \or % \YY >0
                \draw[planar diagram/arrow] (-b\XX) .. controls +(0,0.2) and +(0,-0.2) .. (-t-\YY);
                \or % \XX >0
                \draw[planar diagram/arrow] (-t-\XX) .. controls +(0,-0.2) and +(0,0.2) .. (-b\YY);
                \or % both <0
                \draw[planar diagram/arrow] (-b\XX) .. controls +(0,0.2*\pv{y}+0.025*\XX/\pv{x}-0.025*\YY/\pv{x}) and +(0,0.2*\pv{y}+0.025*\XX/\pv{x}-0.025*\YY/\pv{x}) .. (-b\YY);
                \fi
                \fi
            }
    }},
    planar diagram/.cd,n/.initial=5,x/.initial=0.3,y/.initial=0.7,frame/.style={draw=red},connections/.initial={1/1},arrow/.style={-{stealth}}
}

\usepackage{xparse}
\NewDocumentCommand\NewPlanarDiagram{ O{} D(){3} m }{%
    \begin{tikzpicture}[#1]
    \foreach \diag [count=\c] in {#3} {
        %       \draw(0,\c*0.7) pic[#1]{planar={#2}{\diag}};
        \draw (0,\c*0.8) pic[#1]{planar diagram={n=#2,connections={\diag},arrow/.style={black},x=0.3,y=0.8}};
    }
    \end{tikzpicture}%
}

\NewDocumentCommand\planarDiagram{ O{} D(){3} m }{%
    \begin{scope}[#1]
        \foreach \diag [count=\c] in {#3} {
            \draw (0,\c*0.7) pic[#1]{planar diagram={n=#2,connections={\diag}}};
        }
    \end{scope}
}

\NewDocumentCommand\PlanarDiagram{ O{} D(){3} m }{%
    \begin{tikzpicture}[#1]
    \foreach \diag [count=\c] in {#3} {
        \draw (0,\c*0.7) pic[#1]{planar diagram={n=#2,connections={\diag}}};
    }
    \end{tikzpicture}%
}

相关内容