4

I am often use coordinates of points to draw figure in geometry. I know that, we can add, minus coordinates of points, example

\begin{tikzpicture}
\tkzDefPoints{0/0/C',3/0/D',1/1/B'}
\coordinate (A') at ($(B')+(D')-(C')$);
 \end{tikzpicture}

If I have two points A(1,2,3) and B(4,5,6), how can I define vector AB as (\B)-(\A)?

  • Among the existing proposals, to my knowledge this one might be the most promising one. The open problem, though, is that the transformation is to "recorded". Some advanced transformation recording can be found here. But it seems that you are looking for something else. – marmot Apr 1 at 2:22
  • Asymptote is a good choice – Black Mild Apr 1 at 5:51
  • The bad news for you is that TikZ do not keep track of the 3d points. The code (1,2,3) is just fancy interface for a 2d point (that is a projection of this 3d point). – Kpym Apr 1 at 9:30
6

If you use the coordinates only for drawing, simply define each components of points as variable and then define coordinate points using them. For example:

\documentclass[margin=3.14159mm]{standalone}
\usepackage{tikz,tikz-3dplot}

\begin{document}
\tdplotsetmaincoords{60}{125}
\begin{tikzpicture}
    [scale=0.9,
    tdplot_main_coords,
    axis/.style={-latex,thick},
    vector/.style={-stealth,red,very thick},
    vector guide/.style={dashed,thick}]

%standard tikz coordinate definition using x, y, z coords
% A(2,4,3), B(3,-1,4)
\def\Ax{2}
\def\Ay{4}
\def\Az{3}
\def\Bx{-1}
\def\By{3}
\def\Bz{4}
\coordinate (O) at (0,0,0);
\coordinate (A) at (\Ax,\Ay,\Az);
\coordinate (B) at (\Bx,\By,\Bz);
%draw axes
\draw[axis] (0,0,0) -- (4,0,0) node[anchor=north east]{$x$};
\draw[axis] (0,0,0) -- (0,4,0) node[anchor=north west]{$y$};
\draw[axis] (0,0,0) -- (0,0,5) node[anchor=south]{$z$};
%Dot at point
\fill [blue] (A) circle (2pt);
\fill [blue] (B) circle (2pt);
%draw a vector from O to A and O to B
\draw[vector guide] (O)node[left=1mm]{} -- (A)node[above=-1mm,right]{$P_1(\Ax,\Ay,\Az)$};
\draw[vector guide] (O) -- (B)node[above=-1mm,right]{$P_2(\Bx,\By,\Bz)$};

%draw vector D=AB
\draw[vector] (A) -- (B)node[midway,above,sloped]{$\mathbf{D}$};
\end{tikzpicture}
\end{document}

enter image description here


SUPPLEMENT

With the permission of the answerer, I (Steven B Segletes) show here how the listofitems package can be used to streamline the syntax and maybe provide more readability. With it, I can create the arrays by reading a list, with the syntax \readlist\A{2,4,3}. Then, the expression \A[] will spit back the array 2,4,3, which is sufficient for use in the present MWE. However, the individual components are also accessible as \A[1], \A[2], and \A[3], which can be used for various calculations, as required.

\documentclass[margin=3.14159mm]{standalone}
\usepackage{tikz,tikz-3dplot,listofitems}

\begin{document}
\tdplotsetmaincoords{60}{125}
\begin{tikzpicture}
    [scale=0.9,
    tdplot_main_coords,
    axis/.style={-latex,thick},
    vector/.style={-stealth,red,very thick},
    vector guide/.style={dashed,thick}]

%standard tikz coordinate definition using x, y, z coords
% A(2,4,3), B(3,-1,4)
\readlist\A{2,4,3}
\readlist\B{-1,3,4}
\coordinate (O) at (0,0,0);
\coordinate (A) at (\A[]);
\coordinate (B) at (\B[]);
%draw axes
\draw[axis] (0,0,0) -- (4,0,0) node[anchor=north east]{$x$};
\draw[axis] (0,0,0) -- (0,4,0) node[anchor=north west]{$y$};
\draw[axis] (0,0,0) -- (0,0,5) node[anchor=south]{$z$};
%Dot at point
\fill [blue] (A) circle (2pt);
\fill [blue] (B) circle (2pt);
%draw a vector from O to A and O to B
\draw[vector guide] (O)node[left=1mm]{} -- (A)node[above=-1mm,right]{$P_1(\A[])$};
\draw[vector guide] (O) -- (B)node[above=-1mm,right]{$P_2(\B[])$};

%draw vector D=AB
\draw[vector] (A) -- (B)node[midway,above,sloped]{$\mathbf{D}$};
\end{tikzpicture}
\end{document}
  • Would you mind if I added a supplement to your answer? – Steven B. Segletes Apr 1 at 1:27
  • @StevenB.Segletes, sure. I'd appreciate it. – ferahfeza Apr 1 at 6:59
  • 1
    @ferahfeza margin = 3.14159mm wicked! – L. F. Apr 1 at 9:58
  • 1
    Since language gap can easily occur on an international site as this, I would note for your benefit that "wicked" is a euphemism common to the Northeastern region of the United States, to mean "especially good." Thus, @L.F. was paying you a compliment, not the opposite. – Steven B. Segletes Apr 1 at 10:43
  • 1
    Oh don't worry or fret. I recall being similarly confused the first time I visited Maine, U.S. ...and I live less than 500 miles away from there and speak nominally the same language.. – Steven B. Segletes Apr 1 at 10:52
4

Just for fun, I wrote routines for 3D vector addition, subtraction, cross product and dot product (scalar treated as a 1D vector). I was trying to actually parse expressions of the form \A+\B but eventually gave up.

\documentclass{article}
\usepackage{listofitems}
\usepackage{pgfmath}
\usepackage{amsmath}

\makeatletter
\newcommand{\@vecargs}{}% reserve global names

\newcommand{\vecadd}{}
\newcommand{\vecsub}{}
\newcommand{\vecdot}{}
\newcommand{\veccross}{}
\newcommand{\vecparse}{}

\def\vecadd#1#2#3% #1 = #2 + #3
{\bgroup% local definitions
  \pgfmathsetmacro{\@x}{#2[1]+#3[1]}%
  \pgfmathsetmacro{\@y}{#2[2]+#3[2]}%
  \pgfmathsetmacro{\@z}{#2[3]+#3[3]}%
  \xdef\@vecargs{\@x,\@y,\@z}%
\egroup
\readlist#1{\@vecargs}}

\def\vecsub#1#2#3% #1 = #2 - #3
{\bgroup% local definitions
  \pgfmathsetmacro{\@x}{#2[1]-#3[1]}%
  \pgfmathsetmacro{\@y}{#2[2]-#3[2]}%
  \pgfmathsetmacro{\@z}{#2[3]-#3[3]}%
  \xdef\@vecargs{\@x,\@y,\@z}%
\egroup
\readlist#1{\@vecargs}}

\def\vecdot#1#2#3% #1 = #2 \cdot #3
{\pgfmathsetmacro{\@vecargs}{#2[1]*#3[1] + #2[2]*#3[2] + #3[3]*#3[3]}%
\readlist#1{\@vecargs}}

\def\veccross#1#2#3% #1 = #2 \times #3
{\bgroup% local definitions
  \pgfmathsetmacro{\@x}{#2[2]*#3[3] - #2[3]*#3[2]}%
  \pgfmathsetmacro{\@y}{#2[3]*#3[1] - #2[1]*#3[3]}%
  \pgfmathsetmacro{\@z}{#2[1]*#3[2] - #2[2]*#3[1]}%
  \xdef\@vecargs{\@x,\@y,\@z}%
\egroup
\readlist#1{\@vecargs}}
\makeatother

\begin{document}
\readlist\A{1,2,3}
\readlist\B{4,5,6}

\vecadd\C\A\B
\C[]

\vecsub\C\A\B
\C[]

\vecdot\C\A\B
\C[]

\veccross\C\A\B
\C[]
\end{document}

SUPPLEMENT

I hope John doesn't mind me (Steven B Segletes) adding his sought-after parser to the code. This allows input of the form \vecparse\C{\A+\B}, \vecparse\C{\A - \B}, \vecparse\C{\A .\B}, and \vecparse\C{\A x\B} (extra spaces of no consequence).

Support added not only for \vecparse\C{\A x\B}, but also \vecparse\C{\A x(3,5,6)}, \vecparse\C{(3,5,6)x\B} and \vecparse\C{(1,1,1)x(1,2,3)}.

\documentclass{article}
\usepackage{listofitems}
\usepackage{pgfmath}
\usepackage{amsmath}

\makeatletter
\newcommand{\@vecargs}{}% reserve global names

\newcommand{\vecadd}{}
\newcommand{\vecsub}{}
\newcommand{\vecdot}{}
\newcommand{\veccross}{}
\newcommand{\vecparse}{}

\def\vecadd#1#2#3% #1 = #2 + #3
{\bgroup% local definitions
  \pgfmathsetmacro{\@x}{#2[1]+#3[1]}%
  \pgfmathsetmacro{\@y}{#2[2]+#3[2]}%
  \pgfmathsetmacro{\@z}{#2[3]+#3[3]}%
  \xdef\@vecargs{\@x,\@y,\@z}%
\egroup
\setsepchar{,}%
\readlist#1{\@vecargs}}

\def\vecsub#1#2#3% #1 = #2 - #3
{\bgroup% local definitions
  \pgfmathsetmacro{\@x}{#2[1]-#3[1]}%
  \pgfmathsetmacro{\@y}{#2[2]-#3[2]}%
  \pgfmathsetmacro{\@z}{#2[3]-#3[3]}%
  \xdef\@vecargs{\@x,\@y,\@z}%
\egroup
\setsepchar{,}%
\readlist#1{\@vecargs}}

\def\vecdot#1#2#3% #1 = #2 \cdot #3
{\pgfmathsetmacro{\@vecargs}{#2[1]*#3[1] + #2[2]*#3[2] + #3[3]*#3[3]}%
\setsepchar{,}%
\readlist#1{\@vecargs}}

\def\veccross#1#2#3% #1 = #2 \times #3
{\bgroup% local definitions
  \pgfmathsetmacro{\@x}{#2[2]*#3[3] - #2[3]*#3[2]}%
  \pgfmathsetmacro{\@y}{#2[3]*#3[1] - #2[1]*#3[3]}%
  \pgfmathsetmacro{\@z}{#2[1]*#3[2] - #2[2]*#3[1]}%
  \xdef\@vecargs{\@x,\@y,\@z}%
\egroup
\setsepchar{,}%
\readlist#1{\@vecargs}}

\def\vecparse#1#2{%
  \setsepchar{+||-||x||./(||)}%
  \readlist*\@findop{#2}%
  \ifnum\listlen\@findop[1]=1\relax
    \itemtomacro\@findop[1]\tmpA
  \else
    \itemtomacro\@findop[1,2]\tmpF
    \setsepchar{,}%
    \readlist\tmpE{\tmpF}%
    \def\tmpA{\tmpE}%
  \fi
  \ifnum\listlen\@findop[2]=1\relax
    \itemtomacro\@findop[2]\tmpB
  \else
    \itemtomacro\@findop[2,2]\tmpD
    \setsepchar{,}%
    \readlist\tmpC{\tmpD}%
    \def\tmpB{\tmpC}%
  \fi
  \if+\@findopsep[1]\relax
    \def\tmp{\vecadd#1}%
  \else\if-\@findopsep[1]\relax
    \def\tmp{\vecsub#1}%
  \else\if.\@findopsep[1]\relax
    \def\tmp{\vecdot#1}%
  \else\if x\@findopsep[1]\relax
    \def\tmp{\veccross#1}%
  \fi\fi\fi\fi
  \expandafter\expandafter\expandafter\tmp\expandafter\tmpA\tmpB
}
\makeatother

\begin{document}
\readlist\A{1,2,3}
\readlist\B{4,5,6}

\vecadd\C\A\B
\C[]

VP:\vecparse\C{\A+\B}
\C[]

\vecsub\C\A\B
\C[]

VP:\vecparse\C{\A - \B}
\C[]

\vecdot\C\A\B
\C[]

VP:\vecparse\C{\A .\B}
\C[] 

\veccross\C\A\B
\C[]

VP:\vecparse\C{\A x\B}
\C[]

VP:\vecparse\C{\A x(3,5,6)}
\C[]

VP:\vecparse\C{(3,5,6)x\B}
\C[]

VP:\vecparse\C{(1,1,1)x(1,2,3)}
\C[]

\end{document}

enter image description here

  • That is really nice. – Steven B. Segletes Apr 1 at 19:36
  • I hope you don't mind my edit. – Steven B. Segletes Apr 1 at 20:21
  • 1
    I was thinking more of expressions like \A+(4,5,6) which are a lot easier when \A expands to 1,2,3 directly. – John Kormylo Apr 2 at 13:34
  • 1
    @marmot I think it would be possible, but would require quite a bit more effort. Any time the input is allowed to be in a free format, requiring sub-evaluations of the components that can than comprise larger components...well a more careful approach is required. – Steven B. Segletes Apr 2 at 15:54
  • 1
    @marmot It would likely require an approach like tex.stackexchange.com/questions/332012/…, where an order of operations hierarchy is established, and the input parsed along those lines. But rather than just typesetting the result, vector mechanics needs to be performed. – Steven B. Segletes Apr 2 at 16:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.