how one can write a nice vector parser, something that does pgfvecparse{A=B-C; D=E x F;}
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)
?
tikz-pgf tikzmark
add a comment |
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)
?
tikz-pgf tikzmark
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
add a comment |
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)
?
tikz-pgf tikzmark
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)
?
tikz-pgf tikzmark
tikz-pgf tikzmark
edited Apr 1 at 0:28
minhthien_2016
asked Apr 1 at 0:17
minhthien_2016minhthien_2016
1,4741917
1,4741917
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
add a comment |
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
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
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
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
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
add a comment |
2 Answers
2
active
oldest
votes
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)
defAx{2}
defAy{4}
defAz{3}
defBx{-1}
defBy{3}
defBz{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}
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 readlistA{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)
readlistA{2,4,3}
readlistB{-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
@ferahfezamargin = 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
|
show 7 more comments
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}{}
defvecadd#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}}
defvecsub#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}}
defvecdot#1#2#3% #1 = #2 cdot #3
{pgfmathsetmacro{@vecargs}{#2[1]*#3[1] + #2[2]*#3[2] + #3[3]*#3[3]}%
readlist#1{@vecargs}}
defveccross#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}
readlistA{1,2,3}
readlistB{4,5,6}
vecaddCAB
C
vecsubCAB
C
vecdotCAB
C
veccrossCAB
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 vecparseC{A+B}
, vecparseC{A - B}
, vecparseC{A .B}
, and vecparseC{A xB}
(extra spaces of no consequence).
Support added not only for vecparseC{A xB}
, but also vecparseC{A x(3,5,6)}
, vecparseC{(3,5,6)xB}
and vecparseC{(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}{}
defvecadd#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}}
defvecsub#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}}
defvecdot#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}}
defveccross#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}}
defvecparse#1#2{%
setsepchar{+||-||x||./(||)}%
readlist*@findop{#2}%
ifnumlistlen@findop[1]=1relax
itemtomacro@findop[1]tmpA
else
itemtomacro@findop[1,2]tmpF
setsepchar{,}%
readlisttmpE{tmpF}%
deftmpA{tmpE}%
fi
ifnumlistlen@findop[2]=1relax
itemtomacro@findop[2]tmpB
else
itemtomacro@findop[2,2]tmpD
setsepchar{,}%
readlisttmpC{tmpD}%
deftmpB{tmpC}%
fi
if+@findopsep[1]relax
deftmp{vecadd#1}%
elseif-@findopsep[1]relax
deftmp{vecsub#1}%
elseif.@findopsep[1]relax
deftmp{vecdot#1}%
elseif x@findopsep[1]relax
deftmp{veccross#1}%
fifififi
expandafterexpandafterexpandaftertmpexpandaftertmpAtmpB
}
makeatother
begin{document}
readlistA{1,2,3}
readlistB{4,5,6}
vecaddCAB
C
VP:vecparseC{A+B}
C
vecsubCAB
C
VP:vecparseC{A - B}
C
vecdotCAB
C
VP:vecparseC{A .B}
C
veccrossCAB
C
VP:vecparseC{A xB}
C
VP:vecparseC{A x(3,5,6)}
C
VP:vecparseC{(3,5,6)xB}
C
VP:vecparseC{(1,1,1)x(1,2,3)}
C
end{document}
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 likeA+(4,5,6)
which are a lot easier when A expands to1,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
|
show 6 more comments
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "85"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f482518%2fhow-one-can-write-a-nice-vector-parser-something-that-does-pgfvecparse-a-b%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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)
defAx{2}
defAy{4}
defAz{3}
defBx{-1}
defBy{3}
defBz{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}
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 readlistA{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)
readlistA{2,4,3}
readlistB{-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
@ferahfezamargin = 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
|
show 7 more comments
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)
defAx{2}
defAy{4}
defAz{3}
defBx{-1}
defBy{3}
defBz{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}
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 readlistA{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)
readlistA{2,4,3}
readlistB{-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
@ferahfezamargin = 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
|
show 7 more comments
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)
defAx{2}
defAy{4}
defAz{3}
defBx{-1}
defBy{3}
defBz{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}
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 readlistA{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)
readlistA{2,4,3}
readlistB{-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}
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)
defAx{2}
defAy{4}
defAz{3}
defBx{-1}
defBy{3}
defBz{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}
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 readlistA{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)
readlistA{2,4,3}
readlistB{-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}
edited Apr 1 at 9:56
Steven B. Segletes
163k9207419
163k9207419
answered Apr 1 at 1:05
ferahfezaferahfeza
7,60912033
7,60912033
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
@ferahfezamargin = 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
|
show 7 more comments
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
@ferahfezamargin = 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
Would you mind if I added a supplement to your answer?
– Steven B. Segletes
Apr 1 at 1:27
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
@StevenB.Segletes, sure. I'd appreciate it.
– ferahfeza
Apr 1 at 6:59
1
1
@ferahfeza
margin = 3.14159mm
wicked!– L. F.
Apr 1 at 9:58
@ferahfeza
margin = 3.14159mm
wicked!– L. F.
Apr 1 at 9:58
1
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
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
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
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
|
show 7 more comments
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}{}
defvecadd#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}}
defvecsub#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}}
defvecdot#1#2#3% #1 = #2 cdot #3
{pgfmathsetmacro{@vecargs}{#2[1]*#3[1] + #2[2]*#3[2] + #3[3]*#3[3]}%
readlist#1{@vecargs}}
defveccross#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}
readlistA{1,2,3}
readlistB{4,5,6}
vecaddCAB
C
vecsubCAB
C
vecdotCAB
C
veccrossCAB
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 vecparseC{A+B}
, vecparseC{A - B}
, vecparseC{A .B}
, and vecparseC{A xB}
(extra spaces of no consequence).
Support added not only for vecparseC{A xB}
, but also vecparseC{A x(3,5,6)}
, vecparseC{(3,5,6)xB}
and vecparseC{(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}{}
defvecadd#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}}
defvecsub#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}}
defvecdot#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}}
defveccross#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}}
defvecparse#1#2{%
setsepchar{+||-||x||./(||)}%
readlist*@findop{#2}%
ifnumlistlen@findop[1]=1relax
itemtomacro@findop[1]tmpA
else
itemtomacro@findop[1,2]tmpF
setsepchar{,}%
readlisttmpE{tmpF}%
deftmpA{tmpE}%
fi
ifnumlistlen@findop[2]=1relax
itemtomacro@findop[2]tmpB
else
itemtomacro@findop[2,2]tmpD
setsepchar{,}%
readlisttmpC{tmpD}%
deftmpB{tmpC}%
fi
if+@findopsep[1]relax
deftmp{vecadd#1}%
elseif-@findopsep[1]relax
deftmp{vecsub#1}%
elseif.@findopsep[1]relax
deftmp{vecdot#1}%
elseif x@findopsep[1]relax
deftmp{veccross#1}%
fifififi
expandafterexpandafterexpandaftertmpexpandaftertmpAtmpB
}
makeatother
begin{document}
readlistA{1,2,3}
readlistB{4,5,6}
vecaddCAB
C
VP:vecparseC{A+B}
C
vecsubCAB
C
VP:vecparseC{A - B}
C
vecdotCAB
C
VP:vecparseC{A .B}
C
veccrossCAB
C
VP:vecparseC{A xB}
C
VP:vecparseC{A x(3,5,6)}
C
VP:vecparseC{(3,5,6)xB}
C
VP:vecparseC{(1,1,1)x(1,2,3)}
C
end{document}
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 likeA+(4,5,6)
which are a lot easier when A expands to1,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
|
show 6 more comments
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}{}
defvecadd#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}}
defvecsub#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}}
defvecdot#1#2#3% #1 = #2 cdot #3
{pgfmathsetmacro{@vecargs}{#2[1]*#3[1] + #2[2]*#3[2] + #3[3]*#3[3]}%
readlist#1{@vecargs}}
defveccross#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}
readlistA{1,2,3}
readlistB{4,5,6}
vecaddCAB
C
vecsubCAB
C
vecdotCAB
C
veccrossCAB
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 vecparseC{A+B}
, vecparseC{A - B}
, vecparseC{A .B}
, and vecparseC{A xB}
(extra spaces of no consequence).
Support added not only for vecparseC{A xB}
, but also vecparseC{A x(3,5,6)}
, vecparseC{(3,5,6)xB}
and vecparseC{(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}{}
defvecadd#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}}
defvecsub#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}}
defvecdot#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}}
defveccross#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}}
defvecparse#1#2{%
setsepchar{+||-||x||./(||)}%
readlist*@findop{#2}%
ifnumlistlen@findop[1]=1relax
itemtomacro@findop[1]tmpA
else
itemtomacro@findop[1,2]tmpF
setsepchar{,}%
readlisttmpE{tmpF}%
deftmpA{tmpE}%
fi
ifnumlistlen@findop[2]=1relax
itemtomacro@findop[2]tmpB
else
itemtomacro@findop[2,2]tmpD
setsepchar{,}%
readlisttmpC{tmpD}%
deftmpB{tmpC}%
fi
if+@findopsep[1]relax
deftmp{vecadd#1}%
elseif-@findopsep[1]relax
deftmp{vecsub#1}%
elseif.@findopsep[1]relax
deftmp{vecdot#1}%
elseif x@findopsep[1]relax
deftmp{veccross#1}%
fifififi
expandafterexpandafterexpandaftertmpexpandaftertmpAtmpB
}
makeatother
begin{document}
readlistA{1,2,3}
readlistB{4,5,6}
vecaddCAB
C
VP:vecparseC{A+B}
C
vecsubCAB
C
VP:vecparseC{A - B}
C
vecdotCAB
C
VP:vecparseC{A .B}
C
veccrossCAB
C
VP:vecparseC{A xB}
C
VP:vecparseC{A x(3,5,6)}
C
VP:vecparseC{(3,5,6)xB}
C
VP:vecparseC{(1,1,1)x(1,2,3)}
C
end{document}
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 likeA+(4,5,6)
which are a lot easier when A expands to1,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
|
show 6 more comments
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}{}
defvecadd#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}}
defvecsub#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}}
defvecdot#1#2#3% #1 = #2 cdot #3
{pgfmathsetmacro{@vecargs}{#2[1]*#3[1] + #2[2]*#3[2] + #3[3]*#3[3]}%
readlist#1{@vecargs}}
defveccross#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}
readlistA{1,2,3}
readlistB{4,5,6}
vecaddCAB
C
vecsubCAB
C
vecdotCAB
C
veccrossCAB
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 vecparseC{A+B}
, vecparseC{A - B}
, vecparseC{A .B}
, and vecparseC{A xB}
(extra spaces of no consequence).
Support added not only for vecparseC{A xB}
, but also vecparseC{A x(3,5,6)}
, vecparseC{(3,5,6)xB}
and vecparseC{(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}{}
defvecadd#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}}
defvecsub#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}}
defvecdot#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}}
defveccross#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}}
defvecparse#1#2{%
setsepchar{+||-||x||./(||)}%
readlist*@findop{#2}%
ifnumlistlen@findop[1]=1relax
itemtomacro@findop[1]tmpA
else
itemtomacro@findop[1,2]tmpF
setsepchar{,}%
readlisttmpE{tmpF}%
deftmpA{tmpE}%
fi
ifnumlistlen@findop[2]=1relax
itemtomacro@findop[2]tmpB
else
itemtomacro@findop[2,2]tmpD
setsepchar{,}%
readlisttmpC{tmpD}%
deftmpB{tmpC}%
fi
if+@findopsep[1]relax
deftmp{vecadd#1}%
elseif-@findopsep[1]relax
deftmp{vecsub#1}%
elseif.@findopsep[1]relax
deftmp{vecdot#1}%
elseif x@findopsep[1]relax
deftmp{veccross#1}%
fifififi
expandafterexpandafterexpandaftertmpexpandaftertmpAtmpB
}
makeatother
begin{document}
readlistA{1,2,3}
readlistB{4,5,6}
vecaddCAB
C
VP:vecparseC{A+B}
C
vecsubCAB
C
VP:vecparseC{A - B}
C
vecdotCAB
C
VP:vecparseC{A .B}
C
veccrossCAB
C
VP:vecparseC{A xB}
C
VP:vecparseC{A x(3,5,6)}
C
VP:vecparseC{(3,5,6)xB}
C
VP:vecparseC{(1,1,1)x(1,2,3)}
C
end{document}
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}{}
defvecadd#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}}
defvecsub#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}}
defvecdot#1#2#3% #1 = #2 cdot #3
{pgfmathsetmacro{@vecargs}{#2[1]*#3[1] + #2[2]*#3[2] + #3[3]*#3[3]}%
readlist#1{@vecargs}}
defveccross#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}
readlistA{1,2,3}
readlistB{4,5,6}
vecaddCAB
C
vecsubCAB
C
vecdotCAB
C
veccrossCAB
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 vecparseC{A+B}
, vecparseC{A - B}
, vecparseC{A .B}
, and vecparseC{A xB}
(extra spaces of no consequence).
Support added not only for vecparseC{A xB}
, but also vecparseC{A x(3,5,6)}
, vecparseC{(3,5,6)xB}
and vecparseC{(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}{}
defvecadd#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}}
defvecsub#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}}
defvecdot#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}}
defveccross#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}}
defvecparse#1#2{%
setsepchar{+||-||x||./(||)}%
readlist*@findop{#2}%
ifnumlistlen@findop[1]=1relax
itemtomacro@findop[1]tmpA
else
itemtomacro@findop[1,2]tmpF
setsepchar{,}%
readlisttmpE{tmpF}%
deftmpA{tmpE}%
fi
ifnumlistlen@findop[2]=1relax
itemtomacro@findop[2]tmpB
else
itemtomacro@findop[2,2]tmpD
setsepchar{,}%
readlisttmpC{tmpD}%
deftmpB{tmpC}%
fi
if+@findopsep[1]relax
deftmp{vecadd#1}%
elseif-@findopsep[1]relax
deftmp{vecsub#1}%
elseif.@findopsep[1]relax
deftmp{vecdot#1}%
elseif x@findopsep[1]relax
deftmp{veccross#1}%
fifififi
expandafterexpandafterexpandaftertmpexpandaftertmpAtmpB
}
makeatother
begin{document}
readlistA{1,2,3}
readlistB{4,5,6}
vecaddCAB
C
VP:vecparseC{A+B}
C
vecsubCAB
C
VP:vecparseC{A - B}
C
vecdotCAB
C
VP:vecparseC{A .B}
C
veccrossCAB
C
VP:vecparseC{A xB}
C
VP:vecparseC{A x(3,5,6)}
C
VP:vecparseC{(3,5,6)xB}
C
VP:vecparseC{(1,1,1)x(1,2,3)}
C
end{document}
edited Apr 2 at 15:09
Steven B. Segletes
163k9207419
163k9207419
answered Apr 1 at 19:30
John KormyloJohn Kormylo
46.9k22672
46.9k22672
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 likeA+(4,5,6)
which are a lot easier when A expands to1,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
|
show 6 more comments
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 likeA+(4,5,6)
which are a lot easier when A expands to1,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
That is really nice.
– Steven B. Segletes
Apr 1 at 19:36
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
I hope you don't mind my edit.
– Steven B. Segletes
Apr 1 at 20:21
1
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
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
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
@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
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
@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
|
show 6 more comments
Thanks for contributing an answer to TeX - LaTeX Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f482518%2fhow-one-can-write-a-nice-vector-parser-something-that-does-pgfvecparse-a-b%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
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