Заметным недостатком эстетики в \vec{}
нотации является то, что для "коротких" и "высоких" символов ( a
, i
, v
против b
, k
, l
) векторная нотация overset показывает разницу в высоте относительно базовой линии. Можно ли определить (или переопределить) overset символы, чтобы показать фиксированную, постоянную высоту относительно базовой линии (или любого другого горизонтального стандарта), независимо от символа, на котором он установлен? Ниже приведено быстрое, грубое сравнение статус-кво и цели:
Статус-кво: Высота разная.
Цель: Высота одинакова.
ДРУГОЕ ПРАВКА: Индивидуальный вектор взят изскрипт, написанный пользователем Тоддом Леманом:
\makeatletter
\newlength\xvec@height%
\newlength\xvec@depth%
\newlength\xvec@width%
\newcommand{\xvec}[2][]{%
\ifmmode%
\settoheight{\xvec@height}{$#2$}%
\settodepth{\xvec@depth}{$#2$}%
\settowidth{\xvec@width}{$#2$}%
\else%
\settoheight{\xvec@height}{#2}%
\settodepth{\xvec@depth}{#2}%
\settowidth{\xvec@width}{#2}%
\fi%
\def\xvec@arg{#1}%
\def\xvec@dd{:}%
\def\xvec@d{.}%
\raisebox{.2ex}{\raisebox{\xvec@height}{\rlap{%
\kern.05em% (Because left edge of drawing is at .05em)
\begin{tikzpicture}[scale=1]
\pgfsetroundcap
\draw (.05em,0)--(\[email protected],0);
\draw (\[email protected],0)--(\[email protected], .075em);
\draw (\[email protected],0)--(\[email protected],-.075em);
\ifx\xvec@arg\xvec@d%
\fill(\xvec@width*.45,.5ex) circle (.5pt);%
\else\ifx\xvec@arg\xvec@dd%
\fill(\xvec@width*.30,.5ex) circle (.5pt);%
\fill(\xvec@width*.65,.5ex) circle (.5pt);%
\fi\fi%
\end{tikzpicture}%
}}}%
#2%
}
\makeatother
\let\stdvec\vec
\renewcommand{\vec}[1]{\xvec[]{#1}}
% --- Define \dvec and \ddvec for dotted and double-dotted vectors.
\newcommand{\dvec}[1]{\xvec[.]{#1}}
\newcommand{\ddvec}[1]{\xvec[:]{#1}}
решение1
Вот быстрое решение без применения высоких технологий:
\documentclass{article}
\newcommand{\myvec}[1]{\vec{\vphantom{A}#1}}
\begin{document}
$\myvec{a}\cdot\myvec{b}$
\end{document}
Это автоматически подстроится под подстрочные и надстрочные индексы, но возникнет проблема (см. ниже), если векторный символ находится над символом, высота которого превышает A
.
Немного более сложная версия с использованием \ooalign
заставит вектор находиться на высоте, как будто он находится выше, A
даже если он помещен над чем-то более высоким.
Верхняя строка — это простая версия выше, где третий вектор не выровнен, так как A^2
выше, чем A
. Вторая строка использует код
\newcommand{\myvec}[1]{\ooalign{\hfil$\vec{\vphantom{A}}$\hfil\cr\hfil$#1$\hfil\cr}}
но не будет подстраиваться под изменения размера подстрочного индекса. Если хотите, можете исправить это с помощью \mathchoice
:
\newcommand{\myvec}[1]{\mathchoice
{\ooalign{\hfil$\vec{\vphantom{A}}$\hfil\cr\hfil$#1$\hfil\cr}}
{\ooalign{\hfil$\vec{\vphantom{A}}$\hfil\cr\hfil$#1$\hfil\cr}}
{\ooalign{\hfil$\vec{\vphantom{\scriptstyle A}}$\hfil\cr\hfil$\scriptstyle #1$\hfil\cr}}
{\ooalign{\hfil$\vec{\vphantom{\scriptscriptstyle A}}$\hfil\cr\hfil$\scriptscriptstyle #1$\hfil\cr}}
}
Обратите внимание, что я бы не стал обновлять \vec
команду, так как высокие стрелки выглядят странно, когда находятся над короткими буквами. Сравните \myvec{a}\cdot\myvec{a}
с \vec{a}\cdot\vec{a}
.
Обновлять:
Как последний вариант (мой любимый), можно определить \myvec
с помощью 2 параметров: один необязательный. Обязательный параметр — это напечатанная буква со стрелкой, второй, необязательный параметр — это символ, который задает высоту стрелки.
Так что \myvec[t]{a}
даст вам вектор над a
на высоте t
. Пропуск необязательного аргумента даст вам тот же результат, что и \vec
. Строка выше получена из кода:
$\myvec{a}\cdot\vec{a}\quad\myvec[t]{a}\cdot\vec{t}\quad\myvec[j]{a}\cdot\vec{j}\quad\myvec[b]{a}\cdot\vec{b}\quad\myvec[A]{a}\cdot\vec{A}$
Код \myvec
для
\newcommand{\myvec}[2][]{\vec{\vphantom{#1}#2}}
и он будет корректировать подстрочные и надстрочные индексы, как в $A_{\myvec[t]{a}\cdot\vec{t}}$
.
решение2
Идея заключается в том, чтобы добавить фиксированный символ при измерении высоты, я выбрал T
. Если объект выше, стрелка будет адаптироваться, как показано в (конечно, надуманном) примере.
Код стрелки был улучшен, чтобы его можно было использовать также в нижних и верхних индексах.
\documentclass{article}
\usepackage{tikz}
\makeatletter
\newlength\xvec@height
\newlength\xvec@depth
\newlength\xvec@width
\def\xvec@dd{:}%
\def\xvec@d{.}%
\newcommand{\xvec}[2][]{{\mathpalette\xvec@{{#1}{#2}}}}
\newcommand{\xvec@}[2]{\xvec@@#1#2}
\newcommand{\xvec@@}[3]{%
\settoheight{\xvec@height}{$\m@th#1 T#3$}%
\settodepth{\xvec@depth}{$\m@th#1#3$}%
\settowidth{\xvec@width}{$\m@th#1#3$}%
\def\xvec@arg{#2}%
\raisebox{.2ex}{\raisebox{\xvec@height}{\rlap{%
\kern.05em% (Because left edge of drawing is at .05em)
\begin{tikzpicture}[scale=1]
\pgfsetroundcap
\draw (.05em,0)--(\[email protected],0);
\draw (\[email protected],0)--(\[email protected], .075em);
\draw (\[email protected],0)--(\[email protected],-.075em);
\ifx\xvec@arg\xvec@d
\fill(\xvec@width*.45,.5ex) circle (.5pt);
\else\ifx\xvec@arg\xvec@dd
\fill(\xvec@width*.30,.5ex) circle (.5pt);
\fill(\xvec@width*.65,.5ex) circle (.5pt);
\fi\fi
\end{tikzpicture}%
}}}%
#3%
}
\makeatother
\let\stdvec\vec
\renewcommand{\vec}[1]{\xvec[]{#1}}
% --- Define \dvec and \ddvec for dotted and double-dotted vectors.
\newcommand{\dvec}[1]{\xvec[.]{#1}}
\newcommand{\ddvec}[1]{\xvec[:]{#1}}
\begin{document}
$\vec{a}\cdot\vec{b}$
$\dvec{a}\cdot\dvec{b}$
$\ddvec{a}\cdot\ddvec{b}$
$\dvec{\sum\limits_{k=1}^n a_k}$
$X_{\vec{a}+\vec{b}}$
\end{document}
решение3
Вот мой подход:
Основная идеязаключается в сохранении высоты каждого vec
аргумента s, а затем добавлении a \rule
с нулевой шириной, но с высотой более высокого аргумента, найденной внутри каждого \vec
с его действительным аргументом до того, как он будет действительно выведен на печать. (Расширение происходит внутри a, \savebox
и поэтому перед реальным использованием выражения со всеми его \vec
s максимальная высота, которую необходимо добавить, уже вычислена и добавлена.)
Дополнительные возможности
-- команда для \vec
(named \myVec
), которая использует последнюю найденную высоту (фактически команда, которая заменяет оригинал \vec
внутри базовой команды моего подхода -named \mySHVecs
-)
-- пара команд для сохранения и восстановления текущего значения максимальной высоты, сохраненного для повторного использования (столько раз, сколько необходимо)
\documentclass{article}
\usepackage{amsmath}
\let\oldvec\vec
\makeatletter
\newsavebox\myVec@TempBox %Box for each vector
\newsavebox\myVec@Box %Box for all vectors
\def\max@Height{0pt}
\newcounter{myVecDepth}
% Comand For SameHeightVectors (mySHVecs):
\newcommand\mySHVecs[1]{%
\xdef\max@Height{0pt}
\def\calcMaxVec##1{%
\savebox\myVec@TempBox{\hbox{\ensuremath{##1}}}\ifdim\dimexpr\ht\myVec@TempBox>\max@Height\xdef\max@Height{\the\ht\myVec@TempBox}\fi}
\let\vec\calcMaxVec\savebox\myVec@Box{\vbox{\ensuremath{#1}}}\let\vec\myVec#1\let\vec\oldvec}
% The changed command of vec that uses the maximum height inside the above environment that can be used outside also to use the last maximum height available
\newcommand\myVec[1]{\oldvec{\rule{0pt}{\max@Height}\ensuremath{#1}}}
% Save and restore current height with optional argument to can be used for several saves/restores
\newcommand\saveVecH[1][\tempheight]{\xdef#1{\max@Height}}
\newcommand\useVecH[1][\tempheight]{\xdef\max@Height{#1}}
\makeatother
%User Command that makes the vectors Same Height
%\newcommand\mySHVecs[1]{\begin{SetVecsToHeight}\ensuremath{#1}\end{SetVecsToHeight}}
\begin{document}
Simple command for some variables:
\vspace{0.5cm}
\[\mySHVecs{\vec{a}\cdot\vec{b}\cdot\vec{F_x^2}}\]
\vspace{1cm}
Demonstration of mixing commands \verb|\mySHVecs|, \verb|\oldvec| and \verb|\myVec|:
\vspace{0.5cm}
$\mySHVecs{\vec{a}\cdot\vec{b}\cdot\vec{F_x^2}}-\dfrac{\oldvec{a}}{b}\cdot \myVec{S}=\myVec{0}$
\vspace{1cm}
Demonstration of saved and reused value of height:
\vspace{0.5cm}
\[
\mySHVecs{\vec{a}\cdot\vec{\dfrac{b}{3}}}\saveVecH+\cdot X_{\mySHVecs{\vec{a}+\oldvec{b}}}\cdot\mySHVecs{\useVecH\vec{F_1}}
\]
\end{document}
Выход: