在 LaTeX 中编写宏,通过传递参数获取向量 i,j,k 表示

在 LaTeX 中编写宏,通过传递参数获取向量 i,j,k 表示

我想创建一个新命令\vecty来创建一个向量,它将采用 3 个参数,例如,\vecty{1}{2}{3}这应该显示为$\hat{i}+2\hat{j}+3\hat{k}$ ,如果我给出\vecty{0}{3}{-3}那么它应该显示$3\hat{j}-3\hat{k}

我使用的是 LaTeX。如果能提供一些关于如何使用它的指导,我将不胜感激。我试过\ifthenelse写代码,但结果相当繁琐。你可以看看代码

但我知道代码太糟糕了。因此想知道是否有其他方法可以实现它。请帮助我,我是新手。

答案1

这里有一种方法可以做到这一点:

在此处输入图片描述

笔记:

  • 此更新版本正确处理整数和小数系数为零(+0,0.00)或+输入中带有前导符号、虚假空格和非数字的系数(如上表的第二部分所示)。

  • newtoggle包裹etoolbox因为我更喜欢那种语法而不是\newif语法。但如果你不想包含额外的包,那么调整它以使用\newif其他一些条件方法。此开关会跟踪某个术语是否已被打印,以确保前导正术语没有+

  • 我用了包裹xstring来确定数字是否有前导减号,或者是否为零,但同样,这可以很容易地适应不使用该包。

  • 我建议您使用此宏$\vecty$- 即明确进入数学模式,如下所示。但是,如果您希望使用它而不必按照原始问题进入数学模式,您应该不是用美元符号包围它,而是使用

    \ensuremath{\LeadingSign #1 #2}

    因为这样它就可以在数学模式内部或外部使用。重复一遍,我不是推荐这个,因为这显然是一个数学模式宏。请参阅何时不应使用 \ensuremath 作为数学宏?如果你不同意的话。

进一步增强:

  • 需要\vecty排版三个以上的组件,可以很容易地\Display{}{}为每个组件添加额外的调用 - 不需要进行其他更改。请注意,这尚未经过测试。
  • 这不会删除等于一的系数,也不会在非数字输入的情况下消除系数为零的项:例如\vecty{-1x}{+0y}{1z}
  • 可以使用pgf数学对输入进行数值处理,以便简化系数中的基本表达式。pgf数学函数也可用于转换-0.5-\frac{1}{2}

代码:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xstring}
\usepackage{etoolbox}

\newcommand*{\LeadingSign}{}%
\newcommand*{\CleanedCoefficientWithNoSpaces}{}% coefficient with spaces & "+" removed
\newcommand*{\CleanedCoefficient}{}% digit "1" removed if coefficient is 1, or -1

\newcommand*{\Display}[2]{%
    % #1 = coefficient (may not be a number)
    % #2 = paramater
    %
    % ---------------------------------------------------------------- Clean input
    \StrSubstitute{#1}{ }{}[\CoefficientWithNoSpaces]% eliminate any spaces
    \IfBeginWith{\CoefficientWithNoSpaces}{+}{% eliminate any leading + sign
        \StrSubstitute{\CoefficientWithNoSpaces}{+}{}[\CleanedCoefficientWithNoSpaces]%
    }{%
        \renewcommand*{\CleanedCoefficientWithNoSpaces}{\CoefficientWithNoSpaces}%
    }%
    % ---------------------------------------------------------------- 1, +1, -1 issue
    % If the coefficient is 1, +1, or -1, we need to supress the digit
    \IfEq{\CleanedCoefficientWithNoSpaces}{1}{% coefficient equivalent to +1
        \renewcommand*{\CleanedCoefficient}{}%  eliminate the digit
    }{%
        \IfEq{\CoefficientWithNoSpaces}{-1}{% coefficient equivalent to -1
            \renewcommand*{\CleanedCoefficient}{-}% eliminate the digit (leave sign)
        }{%
            % This is the case of the coefficient not being +1, or -1, so use as is
            \renewcommand*{\CleanedCoefficient}{\CleanedCoefficientWithNoSpaces}% 
            %
            % The issue of the leading sign is dealt with below.  Could have moved the
            % leading sign handling here (with some adjustments above), but that would 
            % have made the code a little harder to read. There is already enough  
            % illiteracy in the world. :-)
        }%
    }%
    % ----------------------------------------------------------------  Leading sign
    % We don't want a + sign for the very first term printed.
    \renewcommand*{\LeadingSign}{}% initalize
    \IfBeginWith{\CleanedCoefficientWithNoSpaces}{-}{%
        % use default empty value (sign is part of number)
        % or for the case of -1, this has already been set above
    }{%
        \iftoggle{PrintedFirstTerm}{%
            \renewcommand*{\LeadingSign}{+}%
        }{%
            % Since a leading term of this vector has not yet been printed 
            % we do not add a + sign
        }%
    }%
    % ----------------------------------------------------------------  Print
    \IfEq{#1}{0}{}{%
        \LeadingSign \CleanedCoefficient #2%
        \global\toggletrue{PrintedFirstTerm}% so next term can have + sign
    }%
}%

\newtoggle{PrintedFirstTerm}
\newcommand*{\vecty}[3]{%
    \global\togglefalse{PrintedFirstTerm}%
    \Display{#1}{\hat{i}} %
    \Display{#2}{\hat{j}}%
    \Display{#3}{\hat{k}}%
    \iftoggle{PrintedFirstTerm}{}{\mathbf{0}}% could also use \vec{0} here
}%

\begin{document}
\[
\begin{array}{ll}
  \verb|$\vecty{1}{2}{3}$|        & \vecty{1}{2}{3}  \\
  \verb|$\vecty{0}{3}{-3}$|       & \vecty{0}{3}{-3} \\
  \verb|$\vecty{0}{0}{0}$|        & \vecty{0}{0}{0}  \\
  \verb|$\vecty{0}{0}{3}$|        & \vecty{0}{0}{3}  \\
  \verb|$\vecty{1}{2}{0}$|        & \vecty{1}{2}{0}  \\
  \verb|$\vecty{0}{3}{3}$|        & \vecty{0}{3}{3}  \\
  \verb|$\vecty{3}{0}{0}$|        & \vecty{3}{0}{0}  \\
  \verb|$\vecty{-1}{1}{0}$|       & \vecty{-1}{1}{0} \\[1.5ex]
  \verb|$\vecty{- 1}{ - 1}{+ 0}$| & \vecty{- 1}{ - 1}{+ 0}\\
  \verb|$\vecty{-1}{-1.0}{+2}$|   & \vecty{-1}{-1.0}{+2}\\
  \verb|$\vecty{-0.0}{+0}{0}$|    & \vecty{-0.0}{+0}{0}\\
  \verb|$\vecty{-0}{+x}{y}$|      & \vecty{-0}{+x}{y}\\
  \verb|$\vecty{-x}{+7}{y}$|      & \vecty{-x}{+7}{y}\\
\end{array}
\]
\end{document}

答案2

\ifcase捕捉 0 \or 1 \else\ifnum >0+/- 情况

\documentclass[12pt]{article}
\newcommand\vecty[3]{\ensuremath{%
  \edef\TEMPnum{#1#2#3}\def\TEMPzero{000}%  
  \ifx\TEMPnum\TEMPzero 0\else%  to make Gonzalo happy :-)
    \ifcase#1\or\hat{i}\ifnum#2>0 +\fi
    \else#1\hat{i}\ifnum#2>0 +\else\ifnum#3>0+\fi\fi\fi
    \ifcase#2 \or\hat{j}\ifnum#3>0 +\fi
    \else #2\hat{j} \ifnum#3>0 + \fi\fi
    \ifcase#3 \or\hat{k}
    \else#3\hat{k}\fi%
    \fi}}

\begin{document}

    \vecty{1}{2}{3} and this should display as $\hat{i}+2\hat{j}+3\hat{k}$

    \vecty{0}{3}{-3} then it should show $3\hat{j}-3\hat{k}$

    \vecty{0}{0}{0} then it should show $0$

    \vecty{2}{0}{2} then it should show $2\hat{i}+2\hat{k}$

\end{document}

在此处输入图片描述

答案3

这是一个使用 lua 的解决方案,它与上述 Peter 的解决方案相比没有任何优势,因此我只是为了比较而发布它(也因为我想练习一下 lua)。使用 lualatex 进行编译。

\documentclass{article}
\usepackage{luacode}

%\begin{filecontents*}{vectyfunc.lua}
\begin{luacode*}
function vecty_make (x,y,z)
    local basis = {"\\hat{\\mathrm{i}}","\\hat{j}","\\hat{k}"}
    local coeffs = {x,y,z}
    local str = ""
    local num = 0
    for i = 1,3 do
        coeffs[i] = string.gsub(coeffs[i]," ","")
        -- if not empty
        if coeffs[i]~="" then
            -- and if not zero
            if tonumber(coeffs[i])~=0 then
                num = num + 1
                -- then put a + if missing a sign
                if tonumber(coeffs[i]) == 1 then coeffs[i] = "" end
                if tonumber(coeffs[i]) == -1 then coeffs[i] = "-" end
                if string.find(coeffs[i],"^[+-]") == nil then
                        coeffs[i]="+"..coeffs[i]
                end
            -- and append to str
            str = str..coeffs[i]..basis[i]
            end
        end
    end

    if num == 0 then
        tex.sprint("\\vec{0}")
    else
        -- remove first sign if a +
        if string.sub(str,1,1) == "+" then
            str = string.sub(str,2)
        end
    tex.sprint(str)
    end

end
\end{luacode*}
%\end{filecontents*}

%\directlua{dofile("vectyfunc.lua")}

\newcommand{\vecty}[3]{
        \directlua{vecty_make("#1","#2","#3")}
}

\begin{document}
\[
\begin{array}{ll}
\verb|$\vecty{1}{2}{3}$|        & \vecty{1}{2}{3}  \\
\verb|$\vecty{0}{3}{-3}$|       & \vecty{0}{3}{-3} \\
\verb|$\vecty{0}{0}{0}$|        & \vecty{0}{0}{0}  \\
\verb|$\vecty{0}{0}{3}$|        & \vecty{0}{0}{3}  \\
\verb|$\vecty{1}{2}{0}$|        & \vecty{1}{2}{0}  \\
\verb|$\vecty{0}{3}{3}$|        & \vecty{0}{3}{3}  \\
\verb|$\vecty{3}{0}{0}$|        & \vecty{3}{0}{0}  \\
\verb|$\vecty{-1}{1}{0}$|       & \vecty{-1}{1}{0} \\
\verb|$\vecty{- 1}{ - 1}{+ 0}$| & \vecty{- 1}{ - 1}{+ 0}\\
\verb|$\vecty{-1}{-1.0}{+2}$|      & \vecty{-1}{-1.0}{+2}\\
\verb|$\vecty{-0.0}{+0}{0}$|      & \vecty{-0.0}{+0}{0}\\
\verb|$\vecty{-0}{+x}{y}$|      & \vecty{-0}{+x}{y}\\
\verb|$\vecty{-x}{+7}{y}$|      & \vecty{-x}{+7}{y}\\
\end{array}
\]
\end{document}

相关内容