TikZ call a macro between subsequent points in a list
In TikZ, I would like to build a macro drawEdges
which for a given list of points produces code that runs through all pairs of two subsequent points, and runs the drawEdge
macro for them. For example,
drawEdges{(0, 0), (1, 0), (1, 1), (0, 1)}
should expand to
drawEdge{(0, 0)}{(1, 0)}
drawEdge{(1, 0)}{(1, 1)}
drawEdge{(1, 1)}{(0, 1)}
The purpose is to cut down on the verbosity of repeating the drawEdge
macro on every pair. How can this be done?
Bonus points if you can also provide a cyclic variant where the expansion includes the pair involving the last and the first point:
drawEdge{(0, 1)}{(0, 0)}
Edit
In my specific case, the drawEdge
macro looks something like this:
newcommand{drawEdge}[2]{
draw[edgeStyle, line width = 1pt] #1 -- #2;
draw[line width = 0.33pt, draw=white] #1 -- #2;
}
Here edgeStyle
includes a decorator to add a custom-styled arrow tip on a position other than the end, and the latter line hollows out the edge. I would also accept a solution which refactors the process into two separate passes
newcommand{drawEdgeFirst}[2]{
draw[edgeStyle, line width = 1pt] #1 -- #2;
}
newcommand{drawEdgeSecond}[2]{
draw[line width = 0.33pt, draw=white] #1 -- #2;
}
with corresponding drawEdgesFirst
and drawEdgesSecond
. Then we could do
newcommand{drawEdges}[1]{
drawEdgesFirst{#1}
drawEdgesSecond{#1}
}
Edit 2
Here's an example of the things I'm drawing. Note that I need exact control of how the hollowing of the edge is done (i.e. its width), so that it connects properly with the arrow tips.
Edit 3
Just realized the hollow edges can be drawn using
newcommand{drawEdge}[2] {
draw[edgeStyle, line width = 0.335pt, double distance = 0.33pt] #1 -- #2;
}
where the hollowing distance can be controlled precisely.
tikz-pgf foreach
add a comment |
In TikZ, I would like to build a macro drawEdges
which for a given list of points produces code that runs through all pairs of two subsequent points, and runs the drawEdge
macro for them. For example,
drawEdges{(0, 0), (1, 0), (1, 1), (0, 1)}
should expand to
drawEdge{(0, 0)}{(1, 0)}
drawEdge{(1, 0)}{(1, 1)}
drawEdge{(1, 1)}{(0, 1)}
The purpose is to cut down on the verbosity of repeating the drawEdge
macro on every pair. How can this be done?
Bonus points if you can also provide a cyclic variant where the expansion includes the pair involving the last and the first point:
drawEdge{(0, 1)}{(0, 0)}
Edit
In my specific case, the drawEdge
macro looks something like this:
newcommand{drawEdge}[2]{
draw[edgeStyle, line width = 1pt] #1 -- #2;
draw[line width = 0.33pt, draw=white] #1 -- #2;
}
Here edgeStyle
includes a decorator to add a custom-styled arrow tip on a position other than the end, and the latter line hollows out the edge. I would also accept a solution which refactors the process into two separate passes
newcommand{drawEdgeFirst}[2]{
draw[edgeStyle, line width = 1pt] #1 -- #2;
}
newcommand{drawEdgeSecond}[2]{
draw[line width = 0.33pt, draw=white] #1 -- #2;
}
with corresponding drawEdgesFirst
and drawEdgesSecond
. Then we could do
newcommand{drawEdges}[1]{
drawEdgesFirst{#1}
drawEdgesSecond{#1}
}
Edit 2
Here's an example of the things I'm drawing. Note that I need exact control of how the hollowing of the edge is done (i.e. its width), so that it connects properly with the arrow tips.
Edit 3
Just realized the hollow edges can be drawn using
newcommand{drawEdge}[2] {
draw[edgeStyle, line width = 0.335pt, double distance = 0.33pt] #1 -- #2;
}
where the hollowing distance can be controlled precisely.
tikz-pgf foreach
add a comment |
In TikZ, I would like to build a macro drawEdges
which for a given list of points produces code that runs through all pairs of two subsequent points, and runs the drawEdge
macro for them. For example,
drawEdges{(0, 0), (1, 0), (1, 1), (0, 1)}
should expand to
drawEdge{(0, 0)}{(1, 0)}
drawEdge{(1, 0)}{(1, 1)}
drawEdge{(1, 1)}{(0, 1)}
The purpose is to cut down on the verbosity of repeating the drawEdge
macro on every pair. How can this be done?
Bonus points if you can also provide a cyclic variant where the expansion includes the pair involving the last and the first point:
drawEdge{(0, 1)}{(0, 0)}
Edit
In my specific case, the drawEdge
macro looks something like this:
newcommand{drawEdge}[2]{
draw[edgeStyle, line width = 1pt] #1 -- #2;
draw[line width = 0.33pt, draw=white] #1 -- #2;
}
Here edgeStyle
includes a decorator to add a custom-styled arrow tip on a position other than the end, and the latter line hollows out the edge. I would also accept a solution which refactors the process into two separate passes
newcommand{drawEdgeFirst}[2]{
draw[edgeStyle, line width = 1pt] #1 -- #2;
}
newcommand{drawEdgeSecond}[2]{
draw[line width = 0.33pt, draw=white] #1 -- #2;
}
with corresponding drawEdgesFirst
and drawEdgesSecond
. Then we could do
newcommand{drawEdges}[1]{
drawEdgesFirst{#1}
drawEdgesSecond{#1}
}
Edit 2
Here's an example of the things I'm drawing. Note that I need exact control of how the hollowing of the edge is done (i.e. its width), so that it connects properly with the arrow tips.
Edit 3
Just realized the hollow edges can be drawn using
newcommand{drawEdge}[2] {
draw[edgeStyle, line width = 0.335pt, double distance = 0.33pt] #1 -- #2;
}
where the hollowing distance can be controlled precisely.
tikz-pgf foreach
In TikZ, I would like to build a macro drawEdges
which for a given list of points produces code that runs through all pairs of two subsequent points, and runs the drawEdge
macro for them. For example,
drawEdges{(0, 0), (1, 0), (1, 1), (0, 1)}
should expand to
drawEdge{(0, 0)}{(1, 0)}
drawEdge{(1, 0)}{(1, 1)}
drawEdge{(1, 1)}{(0, 1)}
The purpose is to cut down on the verbosity of repeating the drawEdge
macro on every pair. How can this be done?
Bonus points if you can also provide a cyclic variant where the expansion includes the pair involving the last and the first point:
drawEdge{(0, 1)}{(0, 0)}
Edit
In my specific case, the drawEdge
macro looks something like this:
newcommand{drawEdge}[2]{
draw[edgeStyle, line width = 1pt] #1 -- #2;
draw[line width = 0.33pt, draw=white] #1 -- #2;
}
Here edgeStyle
includes a decorator to add a custom-styled arrow tip on a position other than the end, and the latter line hollows out the edge. I would also accept a solution which refactors the process into two separate passes
newcommand{drawEdgeFirst}[2]{
draw[edgeStyle, line width = 1pt] #1 -- #2;
}
newcommand{drawEdgeSecond}[2]{
draw[line width = 0.33pt, draw=white] #1 -- #2;
}
with corresponding drawEdgesFirst
and drawEdgesSecond
. Then we could do
newcommand{drawEdges}[1]{
drawEdgesFirst{#1}
drawEdgesSecond{#1}
}
Edit 2
Here's an example of the things I'm drawing. Note that I need exact control of how the hollowing of the edge is done (i.e. its width), so that it connects properly with the arrow tips.
Edit 3
Just realized the hollow edges can be drawn using
newcommand{drawEdge}[2] {
draw[edgeStyle, line width = 0.335pt, double distance = 0.33pt] #1 -- #2;
}
where the hollowing distance can be controlled precisely.
tikz-pgf foreach
tikz-pgf foreach
edited Dec 9 '18 at 23:14
kaba
asked Dec 9 '18 at 17:12
kabakaba
29917
29917
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
Here come the requested macros. I added one possible definition for drawEdge
, which you can change. EDIT: I corrected the orientation of the last segment. And, more importantly, I also added a way to achieve this with a simple tikz style separate arrows
. The basic trick is to use the show path
decoration to draw the segments in the way you suggest. You only have to insert you drawEdge
macro into the lineto code
(and closepath code
, and you are done. Then a simple
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)} -- cycle;
does the trick.
documentclass[tikz,border=3.14mm]{standalone}
usetikzlibrary{decorations.pathreplacing,decorations.markings}
tikzset{separate arrows/.style={%
decoration={show path construction,
lineto code={%
draw [edgeStyle, line width = 0.2]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
draw[line width = 0.1, draw=white]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
},
closepath code={%
draw [edgeStyle, line width = 0.2]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
draw[line width = 0.1, draw=white]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
},
},
postaction=decorate
}}
begin{document}
newcommand{drawEdge}[2]{draw[edgeStyle, line width = 0.2] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;}
newcommand{drawEdges}[1]{%
foreach [count=Y] X in {#1}
{xdeftmpLen{Y}
ifnumY=1
xdefmyLst{"X"}
else
xdefmyLst{myLst,"X"}
fi}
xdefmyLst{{myLst}}
foreach X [remember=X as Y (initially 1)] in {2,...,tmpLen}
{pgfmathsetmacro{myfrom}{myLst[Y-1]}
pgfmathsetmacro{myto}{myLst[X-1]}
drawEdge{myfrom}{myto}
}}
newcommand{drawEdgesCyclic}[1]{%
foreach [count=Y] X in {#1}
{xdeftmpLen{Y}
ifnumY=1
xdefmyLst{"X"}
else
xdefmyLst{myLst,"X"}
fi}
xdefmyLst{{myLst}}
foreach X [remember=X as Y (initially 1)] in {2,...,tmpLen}
{pgfmathsetmacro{myfrom}{myLst[Y-1]}
pgfmathsetmacro{myto}{myLst[X-1]}
drawEdge{myfrom}{myto}
}
pgfmathsetmacro{myfrom}{myLst[tmpLen-1]}
pgfmathsetmacro{myto}{myLst[0]}
drawEdge{myfrom}{myto}
}
begin{tikzpicture}[edgeStyle/.style={latex-stealth}]
drawEdges{(0, 0), (1, 0), (1, 1), (0, 1)}
begin{scope}[xshift=2cm,blue]
drawEdgesCyclic{(0, 0), (1, 0), (1, 1), (0, 1)}
end{scope}
begin{scope}[yshift=-2cm]
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)};
begin{scope}[xshift=2cm,blue]
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)}
-- cycle;
end{scope}
end{scope}
end{tikzpicture}
end{document}
Just for fun: something that approaches your screen shot.
documentclass[tikz,border=3.14mm]{standalone}
usetikzlibrary{decorations.pathreplacing,decorations.markings,calc}
newcommand{drawEdge}[2]{
draw let p1=($(#1)-(#2)$),
n1={veclen(x1,y1} in ifdimn1>60pt [edgeStyle={0.3}{-1}, line width = 0.2]
(#1) -- (#2)fi;
draw [edgeStyle={0.7}{1}, line width =2pt]
(#1) -- (#2);
draw[line width = 1, draw=white]
(#1) -- (#2);
draw[fill=white] (#1) circle (1mm);
draw[fill=white] (#2) circle (1mm);
}
tikzset{separate arrows/.style={%
decoration={show path construction,
lineto code={%
drawEdge{tikzinputsegmentfirst}{tikzinputsegmentlast}
},
closepath code={%
drawEdge{tikzinputsegmentfirst}{tikzinputsegmentlast}
},
},
postaction=decorate
}}
begin{document}
begin{tikzpicture}[edgeStyle/.style n args={2}{-,postaction={decorate,
decoration={markings,mark=at position #1 with {%
fill[black] (#2*0.25,#2*1pt) -- ({#2*(-0.25)},#2*0.15)
--({#2*(-0.25)},#2*1pt);}}}}]
draw[separate arrows,fill=gray!30] plot coordinates {(0, 0) (3, 0) (3, 2) (0, 2)}
-- cycle;
end{tikzpicture}
end{document}
This seems like a general solution to the problem! A nitpick: the last edge in the cyclic case is drawn in the wrong direction. Want to elaborate on the plot coordinates? Perhaps that could be used to neatly solve the refactored approach I mention in my edit.
– kaba
Dec 9 '18 at 18:45
@kaba Good catch, will update. What you are doing in your edit is done bydraw[doubble,...]
. Alternatively, you can usepostaction
for that. Do you have an application where one really needs to draw the stuff in this way?
– marmot
Dec 9 '18 at 18:51
@kaba I made an update that draws your stuff with a simple TikZ style.
– marmot
Dec 9 '18 at 19:14
I added another edit which demonstrates the kind of things I'm drawing. I think the simple TikZ style here cannot apply a style to each edge separately. I think the show path construction decorator you mentioned in another comment could do the trick.
– kaba
Dec 9 '18 at 19:21
@kabashow path construction
is already part of my updated answer.
– marmot
Dec 9 '18 at 19:22
|
show 1 more comment
Here is another proposal that uses a foreach
loop on all points. Not knowing what your macro is doing, I commented on his call.
Update 4 Cyclic at the request of the OP
documentclass[border=5mm]{standalone}
usepackage{tikz}
usetikzlibrary{arrows.meta}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue!75!black,thick,->,>={Straight Barb[angle=50:2pt 3]}}}
foreach point [count=n,remember=point as p (initially point)] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{ node (pointn) at point {};
}
foreach i [remember= i as lasti (initially n)]in {1,...,n}{
drawEdge{(pointlasti.center)}{(pointi.center)}
}
end{tikzpicture}
}
begin{document}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{document}
Update 3
Another possibility with the ifthen else
test:
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially point)] in
{#1}
{ ifthen {p=point} {}
{drawEdge{p}{point}}
}
end{tikzpicture}
}
begin{document}
begin{tikzpicture}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{tikzpicture}
end{document}
Second update (to answer OP's comment)
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially point)] in
{#1}
{
drawEdge{p}{point}
}
end{tikzpicture}
}
begin{document}
begin{tikzpicture}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{tikzpicture}
end{document}
Update
I have removed the parentheses around the parameters of your macro DrawEdge
since the foreach
loop performs an iteration on point coordinates including parentheses.
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
begin{document}
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially {(0,0)})] in
{(1, 0), (1, 1), (0, 1)}
{
drawEdge{p}{point}
% draw[red] p -- point circle(1mm);
}
begin{scope}[xshift=2cm]
foreach point [remember=point as p (initially {(0,1)})] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{
drawEdge{p}{point}
% draw[blue] p -- point circle(1mm);
}
end{scope}
end{tikzpicture}
end{document}
Old answer
documentclass[border=5mm]{standalone}
usepackage{tikz}
begin{document}
begin{tikzpicture}
foreach point [remember=point as p (initially {(0,0)})] in
{(1, 0), (1, 1), (0, 1)}
{
%\drawEdge{p}{point}
draw[red] p -- point circle(1mm);
}
begin{scope}[xshift=2cm]
foreach point [remember=point as p (initially {(0,1)})] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{
%\drawEdge{p}{point}
draw[blue] p -- point circle(1mm);
}
end{scope}
end{tikzpicture}
end{document}
How would you define the macrodrawEdges
? The difficulty seems to be in extracting the first or last point in the list, which is done manually here.
– kaba
Dec 9 '18 at 18:23
I just updated my answer
– AndréC
Dec 9 '18 at 18:37
I think the new solution draws a line from the first point to itself, which is sometimes visible when the end-points are drawn differently.
– kaba
Dec 9 '18 at 18:41
Yes, it all depends on the options of your macro. Most of the time, it doesn't trace anything at all.
– AndréC
Dec 9 '18 at 18:43
With anifthen else
test, it does not trace anything at the first iteration.
– AndréC
Dec 9 '18 at 18:49
|
show 5 more comments
If drawEdge
draws lines, then one can use plot coordinates{<coordinates>}
to achieve this.
A MWE:
documentclass[tikz,border=3mm]{standalone}
usetikzlibrary{calc}
begin{document}
begin{tikzpicture}
draw[smooth cycle,tension=0] plot coordinates{(0,0) (0,1) (1,1) (1,0)};
draw[red] plot coordinates{(0,2) (0,3) (1,3) (1,2)};
end{tikzpicture}
end{document}
Is there a difference between plot coordinates and drawing a path? Each edge should be drawn separately, so for example if the edge's style contains a decorator, then that decorator should be applied to each edge.
– kaba
Dec 9 '18 at 18:27
Your answer reminded me of the correct syntax:plot coordinates
, not justcoordinates
, +1 for that. ;-) @kaba As I mentioned in my answer at the very end, you can do all the decorations and so on, see e.g. this answer, where there is a marking decoration on each connection between two points.
– marmot
Dec 9 '18 at 18:42
add a comment |
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%2f463990%2ftikz-call-a-macro-between-subsequent-points-in-a-list%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here come the requested macros. I added one possible definition for drawEdge
, which you can change. EDIT: I corrected the orientation of the last segment. And, more importantly, I also added a way to achieve this with a simple tikz style separate arrows
. The basic trick is to use the show path
decoration to draw the segments in the way you suggest. You only have to insert you drawEdge
macro into the lineto code
(and closepath code
, and you are done. Then a simple
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)} -- cycle;
does the trick.
documentclass[tikz,border=3.14mm]{standalone}
usetikzlibrary{decorations.pathreplacing,decorations.markings}
tikzset{separate arrows/.style={%
decoration={show path construction,
lineto code={%
draw [edgeStyle, line width = 0.2]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
draw[line width = 0.1, draw=white]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
},
closepath code={%
draw [edgeStyle, line width = 0.2]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
draw[line width = 0.1, draw=white]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
},
},
postaction=decorate
}}
begin{document}
newcommand{drawEdge}[2]{draw[edgeStyle, line width = 0.2] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;}
newcommand{drawEdges}[1]{%
foreach [count=Y] X in {#1}
{xdeftmpLen{Y}
ifnumY=1
xdefmyLst{"X"}
else
xdefmyLst{myLst,"X"}
fi}
xdefmyLst{{myLst}}
foreach X [remember=X as Y (initially 1)] in {2,...,tmpLen}
{pgfmathsetmacro{myfrom}{myLst[Y-1]}
pgfmathsetmacro{myto}{myLst[X-1]}
drawEdge{myfrom}{myto}
}}
newcommand{drawEdgesCyclic}[1]{%
foreach [count=Y] X in {#1}
{xdeftmpLen{Y}
ifnumY=1
xdefmyLst{"X"}
else
xdefmyLst{myLst,"X"}
fi}
xdefmyLst{{myLst}}
foreach X [remember=X as Y (initially 1)] in {2,...,tmpLen}
{pgfmathsetmacro{myfrom}{myLst[Y-1]}
pgfmathsetmacro{myto}{myLst[X-1]}
drawEdge{myfrom}{myto}
}
pgfmathsetmacro{myfrom}{myLst[tmpLen-1]}
pgfmathsetmacro{myto}{myLst[0]}
drawEdge{myfrom}{myto}
}
begin{tikzpicture}[edgeStyle/.style={latex-stealth}]
drawEdges{(0, 0), (1, 0), (1, 1), (0, 1)}
begin{scope}[xshift=2cm,blue]
drawEdgesCyclic{(0, 0), (1, 0), (1, 1), (0, 1)}
end{scope}
begin{scope}[yshift=-2cm]
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)};
begin{scope}[xshift=2cm,blue]
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)}
-- cycle;
end{scope}
end{scope}
end{tikzpicture}
end{document}
Just for fun: something that approaches your screen shot.
documentclass[tikz,border=3.14mm]{standalone}
usetikzlibrary{decorations.pathreplacing,decorations.markings,calc}
newcommand{drawEdge}[2]{
draw let p1=($(#1)-(#2)$),
n1={veclen(x1,y1} in ifdimn1>60pt [edgeStyle={0.3}{-1}, line width = 0.2]
(#1) -- (#2)fi;
draw [edgeStyle={0.7}{1}, line width =2pt]
(#1) -- (#2);
draw[line width = 1, draw=white]
(#1) -- (#2);
draw[fill=white] (#1) circle (1mm);
draw[fill=white] (#2) circle (1mm);
}
tikzset{separate arrows/.style={%
decoration={show path construction,
lineto code={%
drawEdge{tikzinputsegmentfirst}{tikzinputsegmentlast}
},
closepath code={%
drawEdge{tikzinputsegmentfirst}{tikzinputsegmentlast}
},
},
postaction=decorate
}}
begin{document}
begin{tikzpicture}[edgeStyle/.style n args={2}{-,postaction={decorate,
decoration={markings,mark=at position #1 with {%
fill[black] (#2*0.25,#2*1pt) -- ({#2*(-0.25)},#2*0.15)
--({#2*(-0.25)},#2*1pt);}}}}]
draw[separate arrows,fill=gray!30] plot coordinates {(0, 0) (3, 0) (3, 2) (0, 2)}
-- cycle;
end{tikzpicture}
end{document}
This seems like a general solution to the problem! A nitpick: the last edge in the cyclic case is drawn in the wrong direction. Want to elaborate on the plot coordinates? Perhaps that could be used to neatly solve the refactored approach I mention in my edit.
– kaba
Dec 9 '18 at 18:45
@kaba Good catch, will update. What you are doing in your edit is done bydraw[doubble,...]
. Alternatively, you can usepostaction
for that. Do you have an application where one really needs to draw the stuff in this way?
– marmot
Dec 9 '18 at 18:51
@kaba I made an update that draws your stuff with a simple TikZ style.
– marmot
Dec 9 '18 at 19:14
I added another edit which demonstrates the kind of things I'm drawing. I think the simple TikZ style here cannot apply a style to each edge separately. I think the show path construction decorator you mentioned in another comment could do the trick.
– kaba
Dec 9 '18 at 19:21
@kabashow path construction
is already part of my updated answer.
– marmot
Dec 9 '18 at 19:22
|
show 1 more comment
Here come the requested macros. I added one possible definition for drawEdge
, which you can change. EDIT: I corrected the orientation of the last segment. And, more importantly, I also added a way to achieve this with a simple tikz style separate arrows
. The basic trick is to use the show path
decoration to draw the segments in the way you suggest. You only have to insert you drawEdge
macro into the lineto code
(and closepath code
, and you are done. Then a simple
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)} -- cycle;
does the trick.
documentclass[tikz,border=3.14mm]{standalone}
usetikzlibrary{decorations.pathreplacing,decorations.markings}
tikzset{separate arrows/.style={%
decoration={show path construction,
lineto code={%
draw [edgeStyle, line width = 0.2]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
draw[line width = 0.1, draw=white]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
},
closepath code={%
draw [edgeStyle, line width = 0.2]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
draw[line width = 0.1, draw=white]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
},
},
postaction=decorate
}}
begin{document}
newcommand{drawEdge}[2]{draw[edgeStyle, line width = 0.2] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;}
newcommand{drawEdges}[1]{%
foreach [count=Y] X in {#1}
{xdeftmpLen{Y}
ifnumY=1
xdefmyLst{"X"}
else
xdefmyLst{myLst,"X"}
fi}
xdefmyLst{{myLst}}
foreach X [remember=X as Y (initially 1)] in {2,...,tmpLen}
{pgfmathsetmacro{myfrom}{myLst[Y-1]}
pgfmathsetmacro{myto}{myLst[X-1]}
drawEdge{myfrom}{myto}
}}
newcommand{drawEdgesCyclic}[1]{%
foreach [count=Y] X in {#1}
{xdeftmpLen{Y}
ifnumY=1
xdefmyLst{"X"}
else
xdefmyLst{myLst,"X"}
fi}
xdefmyLst{{myLst}}
foreach X [remember=X as Y (initially 1)] in {2,...,tmpLen}
{pgfmathsetmacro{myfrom}{myLst[Y-1]}
pgfmathsetmacro{myto}{myLst[X-1]}
drawEdge{myfrom}{myto}
}
pgfmathsetmacro{myfrom}{myLst[tmpLen-1]}
pgfmathsetmacro{myto}{myLst[0]}
drawEdge{myfrom}{myto}
}
begin{tikzpicture}[edgeStyle/.style={latex-stealth}]
drawEdges{(0, 0), (1, 0), (1, 1), (0, 1)}
begin{scope}[xshift=2cm,blue]
drawEdgesCyclic{(0, 0), (1, 0), (1, 1), (0, 1)}
end{scope}
begin{scope}[yshift=-2cm]
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)};
begin{scope}[xshift=2cm,blue]
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)}
-- cycle;
end{scope}
end{scope}
end{tikzpicture}
end{document}
Just for fun: something that approaches your screen shot.
documentclass[tikz,border=3.14mm]{standalone}
usetikzlibrary{decorations.pathreplacing,decorations.markings,calc}
newcommand{drawEdge}[2]{
draw let p1=($(#1)-(#2)$),
n1={veclen(x1,y1} in ifdimn1>60pt [edgeStyle={0.3}{-1}, line width = 0.2]
(#1) -- (#2)fi;
draw [edgeStyle={0.7}{1}, line width =2pt]
(#1) -- (#2);
draw[line width = 1, draw=white]
(#1) -- (#2);
draw[fill=white] (#1) circle (1mm);
draw[fill=white] (#2) circle (1mm);
}
tikzset{separate arrows/.style={%
decoration={show path construction,
lineto code={%
drawEdge{tikzinputsegmentfirst}{tikzinputsegmentlast}
},
closepath code={%
drawEdge{tikzinputsegmentfirst}{tikzinputsegmentlast}
},
},
postaction=decorate
}}
begin{document}
begin{tikzpicture}[edgeStyle/.style n args={2}{-,postaction={decorate,
decoration={markings,mark=at position #1 with {%
fill[black] (#2*0.25,#2*1pt) -- ({#2*(-0.25)},#2*0.15)
--({#2*(-0.25)},#2*1pt);}}}}]
draw[separate arrows,fill=gray!30] plot coordinates {(0, 0) (3, 0) (3, 2) (0, 2)}
-- cycle;
end{tikzpicture}
end{document}
This seems like a general solution to the problem! A nitpick: the last edge in the cyclic case is drawn in the wrong direction. Want to elaborate on the plot coordinates? Perhaps that could be used to neatly solve the refactored approach I mention in my edit.
– kaba
Dec 9 '18 at 18:45
@kaba Good catch, will update. What you are doing in your edit is done bydraw[doubble,...]
. Alternatively, you can usepostaction
for that. Do you have an application where one really needs to draw the stuff in this way?
– marmot
Dec 9 '18 at 18:51
@kaba I made an update that draws your stuff with a simple TikZ style.
– marmot
Dec 9 '18 at 19:14
I added another edit which demonstrates the kind of things I'm drawing. I think the simple TikZ style here cannot apply a style to each edge separately. I think the show path construction decorator you mentioned in another comment could do the trick.
– kaba
Dec 9 '18 at 19:21
@kabashow path construction
is already part of my updated answer.
– marmot
Dec 9 '18 at 19:22
|
show 1 more comment
Here come the requested macros. I added one possible definition for drawEdge
, which you can change. EDIT: I corrected the orientation of the last segment. And, more importantly, I also added a way to achieve this with a simple tikz style separate arrows
. The basic trick is to use the show path
decoration to draw the segments in the way you suggest. You only have to insert you drawEdge
macro into the lineto code
(and closepath code
, and you are done. Then a simple
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)} -- cycle;
does the trick.
documentclass[tikz,border=3.14mm]{standalone}
usetikzlibrary{decorations.pathreplacing,decorations.markings}
tikzset{separate arrows/.style={%
decoration={show path construction,
lineto code={%
draw [edgeStyle, line width = 0.2]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
draw[line width = 0.1, draw=white]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
},
closepath code={%
draw [edgeStyle, line width = 0.2]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
draw[line width = 0.1, draw=white]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
},
},
postaction=decorate
}}
begin{document}
newcommand{drawEdge}[2]{draw[edgeStyle, line width = 0.2] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;}
newcommand{drawEdges}[1]{%
foreach [count=Y] X in {#1}
{xdeftmpLen{Y}
ifnumY=1
xdefmyLst{"X"}
else
xdefmyLst{myLst,"X"}
fi}
xdefmyLst{{myLst}}
foreach X [remember=X as Y (initially 1)] in {2,...,tmpLen}
{pgfmathsetmacro{myfrom}{myLst[Y-1]}
pgfmathsetmacro{myto}{myLst[X-1]}
drawEdge{myfrom}{myto}
}}
newcommand{drawEdgesCyclic}[1]{%
foreach [count=Y] X in {#1}
{xdeftmpLen{Y}
ifnumY=1
xdefmyLst{"X"}
else
xdefmyLst{myLst,"X"}
fi}
xdefmyLst{{myLst}}
foreach X [remember=X as Y (initially 1)] in {2,...,tmpLen}
{pgfmathsetmacro{myfrom}{myLst[Y-1]}
pgfmathsetmacro{myto}{myLst[X-1]}
drawEdge{myfrom}{myto}
}
pgfmathsetmacro{myfrom}{myLst[tmpLen-1]}
pgfmathsetmacro{myto}{myLst[0]}
drawEdge{myfrom}{myto}
}
begin{tikzpicture}[edgeStyle/.style={latex-stealth}]
drawEdges{(0, 0), (1, 0), (1, 1), (0, 1)}
begin{scope}[xshift=2cm,blue]
drawEdgesCyclic{(0, 0), (1, 0), (1, 1), (0, 1)}
end{scope}
begin{scope}[yshift=-2cm]
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)};
begin{scope}[xshift=2cm,blue]
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)}
-- cycle;
end{scope}
end{scope}
end{tikzpicture}
end{document}
Just for fun: something that approaches your screen shot.
documentclass[tikz,border=3.14mm]{standalone}
usetikzlibrary{decorations.pathreplacing,decorations.markings,calc}
newcommand{drawEdge}[2]{
draw let p1=($(#1)-(#2)$),
n1={veclen(x1,y1} in ifdimn1>60pt [edgeStyle={0.3}{-1}, line width = 0.2]
(#1) -- (#2)fi;
draw [edgeStyle={0.7}{1}, line width =2pt]
(#1) -- (#2);
draw[line width = 1, draw=white]
(#1) -- (#2);
draw[fill=white] (#1) circle (1mm);
draw[fill=white] (#2) circle (1mm);
}
tikzset{separate arrows/.style={%
decoration={show path construction,
lineto code={%
drawEdge{tikzinputsegmentfirst}{tikzinputsegmentlast}
},
closepath code={%
drawEdge{tikzinputsegmentfirst}{tikzinputsegmentlast}
},
},
postaction=decorate
}}
begin{document}
begin{tikzpicture}[edgeStyle/.style n args={2}{-,postaction={decorate,
decoration={markings,mark=at position #1 with {%
fill[black] (#2*0.25,#2*1pt) -- ({#2*(-0.25)},#2*0.15)
--({#2*(-0.25)},#2*1pt);}}}}]
draw[separate arrows,fill=gray!30] plot coordinates {(0, 0) (3, 0) (3, 2) (0, 2)}
-- cycle;
end{tikzpicture}
end{document}
Here come the requested macros. I added one possible definition for drawEdge
, which you can change. EDIT: I corrected the orientation of the last segment. And, more importantly, I also added a way to achieve this with a simple tikz style separate arrows
. The basic trick is to use the show path
decoration to draw the segments in the way you suggest. You only have to insert you drawEdge
macro into the lineto code
(and closepath code
, and you are done. Then a simple
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)} -- cycle;
does the trick.
documentclass[tikz,border=3.14mm]{standalone}
usetikzlibrary{decorations.pathreplacing,decorations.markings}
tikzset{separate arrows/.style={%
decoration={show path construction,
lineto code={%
draw [edgeStyle, line width = 0.2]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
draw[line width = 0.1, draw=white]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
},
closepath code={%
draw [edgeStyle, line width = 0.2]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
draw[line width = 0.1, draw=white]
(tikzinputsegmentfirst) -- (tikzinputsegmentlast);
},
},
postaction=decorate
}}
begin{document}
newcommand{drawEdge}[2]{draw[edgeStyle, line width = 0.2] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;}
newcommand{drawEdges}[1]{%
foreach [count=Y] X in {#1}
{xdeftmpLen{Y}
ifnumY=1
xdefmyLst{"X"}
else
xdefmyLst{myLst,"X"}
fi}
xdefmyLst{{myLst}}
foreach X [remember=X as Y (initially 1)] in {2,...,tmpLen}
{pgfmathsetmacro{myfrom}{myLst[Y-1]}
pgfmathsetmacro{myto}{myLst[X-1]}
drawEdge{myfrom}{myto}
}}
newcommand{drawEdgesCyclic}[1]{%
foreach [count=Y] X in {#1}
{xdeftmpLen{Y}
ifnumY=1
xdefmyLst{"X"}
else
xdefmyLst{myLst,"X"}
fi}
xdefmyLst{{myLst}}
foreach X [remember=X as Y (initially 1)] in {2,...,tmpLen}
{pgfmathsetmacro{myfrom}{myLst[Y-1]}
pgfmathsetmacro{myto}{myLst[X-1]}
drawEdge{myfrom}{myto}
}
pgfmathsetmacro{myfrom}{myLst[tmpLen-1]}
pgfmathsetmacro{myto}{myLst[0]}
drawEdge{myfrom}{myto}
}
begin{tikzpicture}[edgeStyle/.style={latex-stealth}]
drawEdges{(0, 0), (1, 0), (1, 1), (0, 1)}
begin{scope}[xshift=2cm,blue]
drawEdgesCyclic{(0, 0), (1, 0), (1, 1), (0, 1)}
end{scope}
begin{scope}[yshift=-2cm]
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)};
begin{scope}[xshift=2cm,blue]
draw[separate arrows] plot coordinates {(0, 0) (1, 0) (1, 1) (0, 1)}
-- cycle;
end{scope}
end{scope}
end{tikzpicture}
end{document}
Just for fun: something that approaches your screen shot.
documentclass[tikz,border=3.14mm]{standalone}
usetikzlibrary{decorations.pathreplacing,decorations.markings,calc}
newcommand{drawEdge}[2]{
draw let p1=($(#1)-(#2)$),
n1={veclen(x1,y1} in ifdimn1>60pt [edgeStyle={0.3}{-1}, line width = 0.2]
(#1) -- (#2)fi;
draw [edgeStyle={0.7}{1}, line width =2pt]
(#1) -- (#2);
draw[line width = 1, draw=white]
(#1) -- (#2);
draw[fill=white] (#1) circle (1mm);
draw[fill=white] (#2) circle (1mm);
}
tikzset{separate arrows/.style={%
decoration={show path construction,
lineto code={%
drawEdge{tikzinputsegmentfirst}{tikzinputsegmentlast}
},
closepath code={%
drawEdge{tikzinputsegmentfirst}{tikzinputsegmentlast}
},
},
postaction=decorate
}}
begin{document}
begin{tikzpicture}[edgeStyle/.style n args={2}{-,postaction={decorate,
decoration={markings,mark=at position #1 with {%
fill[black] (#2*0.25,#2*1pt) -- ({#2*(-0.25)},#2*0.15)
--({#2*(-0.25)},#2*1pt);}}}}]
draw[separate arrows,fill=gray!30] plot coordinates {(0, 0) (3, 0) (3, 2) (0, 2)}
-- cycle;
end{tikzpicture}
end{document}
edited Dec 9 '18 at 22:01
answered Dec 9 '18 at 17:36
marmotmarmot
97.3k4112214
97.3k4112214
This seems like a general solution to the problem! A nitpick: the last edge in the cyclic case is drawn in the wrong direction. Want to elaborate on the plot coordinates? Perhaps that could be used to neatly solve the refactored approach I mention in my edit.
– kaba
Dec 9 '18 at 18:45
@kaba Good catch, will update. What you are doing in your edit is done bydraw[doubble,...]
. Alternatively, you can usepostaction
for that. Do you have an application where one really needs to draw the stuff in this way?
– marmot
Dec 9 '18 at 18:51
@kaba I made an update that draws your stuff with a simple TikZ style.
– marmot
Dec 9 '18 at 19:14
I added another edit which demonstrates the kind of things I'm drawing. I think the simple TikZ style here cannot apply a style to each edge separately. I think the show path construction decorator you mentioned in another comment could do the trick.
– kaba
Dec 9 '18 at 19:21
@kabashow path construction
is already part of my updated answer.
– marmot
Dec 9 '18 at 19:22
|
show 1 more comment
This seems like a general solution to the problem! A nitpick: the last edge in the cyclic case is drawn in the wrong direction. Want to elaborate on the plot coordinates? Perhaps that could be used to neatly solve the refactored approach I mention in my edit.
– kaba
Dec 9 '18 at 18:45
@kaba Good catch, will update. What you are doing in your edit is done bydraw[doubble,...]
. Alternatively, you can usepostaction
for that. Do you have an application where one really needs to draw the stuff in this way?
– marmot
Dec 9 '18 at 18:51
@kaba I made an update that draws your stuff with a simple TikZ style.
– marmot
Dec 9 '18 at 19:14
I added another edit which demonstrates the kind of things I'm drawing. I think the simple TikZ style here cannot apply a style to each edge separately. I think the show path construction decorator you mentioned in another comment could do the trick.
– kaba
Dec 9 '18 at 19:21
@kabashow path construction
is already part of my updated answer.
– marmot
Dec 9 '18 at 19:22
This seems like a general solution to the problem! A nitpick: the last edge in the cyclic case is drawn in the wrong direction. Want to elaborate on the plot coordinates? Perhaps that could be used to neatly solve the refactored approach I mention in my edit.
– kaba
Dec 9 '18 at 18:45
This seems like a general solution to the problem! A nitpick: the last edge in the cyclic case is drawn in the wrong direction. Want to elaborate on the plot coordinates? Perhaps that could be used to neatly solve the refactored approach I mention in my edit.
– kaba
Dec 9 '18 at 18:45
@kaba Good catch, will update. What you are doing in your edit is done by
draw[doubble,...]
. Alternatively, you can use postaction
for that. Do you have an application where one really needs to draw the stuff in this way?– marmot
Dec 9 '18 at 18:51
@kaba Good catch, will update. What you are doing in your edit is done by
draw[doubble,...]
. Alternatively, you can use postaction
for that. Do you have an application where one really needs to draw the stuff in this way?– marmot
Dec 9 '18 at 18:51
@kaba I made an update that draws your stuff with a simple TikZ style.
– marmot
Dec 9 '18 at 19:14
@kaba I made an update that draws your stuff with a simple TikZ style.
– marmot
Dec 9 '18 at 19:14
I added another edit which demonstrates the kind of things I'm drawing. I think the simple TikZ style here cannot apply a style to each edge separately. I think the show path construction decorator you mentioned in another comment could do the trick.
– kaba
Dec 9 '18 at 19:21
I added another edit which demonstrates the kind of things I'm drawing. I think the simple TikZ style here cannot apply a style to each edge separately. I think the show path construction decorator you mentioned in another comment could do the trick.
– kaba
Dec 9 '18 at 19:21
@kaba
show path construction
is already part of my updated answer.– marmot
Dec 9 '18 at 19:22
@kaba
show path construction
is already part of my updated answer.– marmot
Dec 9 '18 at 19:22
|
show 1 more comment
Here is another proposal that uses a foreach
loop on all points. Not knowing what your macro is doing, I commented on his call.
Update 4 Cyclic at the request of the OP
documentclass[border=5mm]{standalone}
usepackage{tikz}
usetikzlibrary{arrows.meta}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue!75!black,thick,->,>={Straight Barb[angle=50:2pt 3]}}}
foreach point [count=n,remember=point as p (initially point)] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{ node (pointn) at point {};
}
foreach i [remember= i as lasti (initially n)]in {1,...,n}{
drawEdge{(pointlasti.center)}{(pointi.center)}
}
end{tikzpicture}
}
begin{document}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{document}
Update 3
Another possibility with the ifthen else
test:
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially point)] in
{#1}
{ ifthen {p=point} {}
{drawEdge{p}{point}}
}
end{tikzpicture}
}
begin{document}
begin{tikzpicture}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{tikzpicture}
end{document}
Second update (to answer OP's comment)
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially point)] in
{#1}
{
drawEdge{p}{point}
}
end{tikzpicture}
}
begin{document}
begin{tikzpicture}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{tikzpicture}
end{document}
Update
I have removed the parentheses around the parameters of your macro DrawEdge
since the foreach
loop performs an iteration on point coordinates including parentheses.
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
begin{document}
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially {(0,0)})] in
{(1, 0), (1, 1), (0, 1)}
{
drawEdge{p}{point}
% draw[red] p -- point circle(1mm);
}
begin{scope}[xshift=2cm]
foreach point [remember=point as p (initially {(0,1)})] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{
drawEdge{p}{point}
% draw[blue] p -- point circle(1mm);
}
end{scope}
end{tikzpicture}
end{document}
Old answer
documentclass[border=5mm]{standalone}
usepackage{tikz}
begin{document}
begin{tikzpicture}
foreach point [remember=point as p (initially {(0,0)})] in
{(1, 0), (1, 1), (0, 1)}
{
%\drawEdge{p}{point}
draw[red] p -- point circle(1mm);
}
begin{scope}[xshift=2cm]
foreach point [remember=point as p (initially {(0,1)})] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{
%\drawEdge{p}{point}
draw[blue] p -- point circle(1mm);
}
end{scope}
end{tikzpicture}
end{document}
How would you define the macrodrawEdges
? The difficulty seems to be in extracting the first or last point in the list, which is done manually here.
– kaba
Dec 9 '18 at 18:23
I just updated my answer
– AndréC
Dec 9 '18 at 18:37
I think the new solution draws a line from the first point to itself, which is sometimes visible when the end-points are drawn differently.
– kaba
Dec 9 '18 at 18:41
Yes, it all depends on the options of your macro. Most of the time, it doesn't trace anything at all.
– AndréC
Dec 9 '18 at 18:43
With anifthen else
test, it does not trace anything at the first iteration.
– AndréC
Dec 9 '18 at 18:49
|
show 5 more comments
Here is another proposal that uses a foreach
loop on all points. Not knowing what your macro is doing, I commented on his call.
Update 4 Cyclic at the request of the OP
documentclass[border=5mm]{standalone}
usepackage{tikz}
usetikzlibrary{arrows.meta}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue!75!black,thick,->,>={Straight Barb[angle=50:2pt 3]}}}
foreach point [count=n,remember=point as p (initially point)] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{ node (pointn) at point {};
}
foreach i [remember= i as lasti (initially n)]in {1,...,n}{
drawEdge{(pointlasti.center)}{(pointi.center)}
}
end{tikzpicture}
}
begin{document}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{document}
Update 3
Another possibility with the ifthen else
test:
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially point)] in
{#1}
{ ifthen {p=point} {}
{drawEdge{p}{point}}
}
end{tikzpicture}
}
begin{document}
begin{tikzpicture}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{tikzpicture}
end{document}
Second update (to answer OP's comment)
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially point)] in
{#1}
{
drawEdge{p}{point}
}
end{tikzpicture}
}
begin{document}
begin{tikzpicture}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{tikzpicture}
end{document}
Update
I have removed the parentheses around the parameters of your macro DrawEdge
since the foreach
loop performs an iteration on point coordinates including parentheses.
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
begin{document}
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially {(0,0)})] in
{(1, 0), (1, 1), (0, 1)}
{
drawEdge{p}{point}
% draw[red] p -- point circle(1mm);
}
begin{scope}[xshift=2cm]
foreach point [remember=point as p (initially {(0,1)})] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{
drawEdge{p}{point}
% draw[blue] p -- point circle(1mm);
}
end{scope}
end{tikzpicture}
end{document}
Old answer
documentclass[border=5mm]{standalone}
usepackage{tikz}
begin{document}
begin{tikzpicture}
foreach point [remember=point as p (initially {(0,0)})] in
{(1, 0), (1, 1), (0, 1)}
{
%\drawEdge{p}{point}
draw[red] p -- point circle(1mm);
}
begin{scope}[xshift=2cm]
foreach point [remember=point as p (initially {(0,1)})] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{
%\drawEdge{p}{point}
draw[blue] p -- point circle(1mm);
}
end{scope}
end{tikzpicture}
end{document}
How would you define the macrodrawEdges
? The difficulty seems to be in extracting the first or last point in the list, which is done manually here.
– kaba
Dec 9 '18 at 18:23
I just updated my answer
– AndréC
Dec 9 '18 at 18:37
I think the new solution draws a line from the first point to itself, which is sometimes visible when the end-points are drawn differently.
– kaba
Dec 9 '18 at 18:41
Yes, it all depends on the options of your macro. Most of the time, it doesn't trace anything at all.
– AndréC
Dec 9 '18 at 18:43
With anifthen else
test, it does not trace anything at the first iteration.
– AndréC
Dec 9 '18 at 18:49
|
show 5 more comments
Here is another proposal that uses a foreach
loop on all points. Not knowing what your macro is doing, I commented on his call.
Update 4 Cyclic at the request of the OP
documentclass[border=5mm]{standalone}
usepackage{tikz}
usetikzlibrary{arrows.meta}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue!75!black,thick,->,>={Straight Barb[angle=50:2pt 3]}}}
foreach point [count=n,remember=point as p (initially point)] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{ node (pointn) at point {};
}
foreach i [remember= i as lasti (initially n)]in {1,...,n}{
drawEdge{(pointlasti.center)}{(pointi.center)}
}
end{tikzpicture}
}
begin{document}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{document}
Update 3
Another possibility with the ifthen else
test:
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially point)] in
{#1}
{ ifthen {p=point} {}
{drawEdge{p}{point}}
}
end{tikzpicture}
}
begin{document}
begin{tikzpicture}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{tikzpicture}
end{document}
Second update (to answer OP's comment)
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially point)] in
{#1}
{
drawEdge{p}{point}
}
end{tikzpicture}
}
begin{document}
begin{tikzpicture}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{tikzpicture}
end{document}
Update
I have removed the parentheses around the parameters of your macro DrawEdge
since the foreach
loop performs an iteration on point coordinates including parentheses.
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
begin{document}
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially {(0,0)})] in
{(1, 0), (1, 1), (0, 1)}
{
drawEdge{p}{point}
% draw[red] p -- point circle(1mm);
}
begin{scope}[xshift=2cm]
foreach point [remember=point as p (initially {(0,1)})] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{
drawEdge{p}{point}
% draw[blue] p -- point circle(1mm);
}
end{scope}
end{tikzpicture}
end{document}
Old answer
documentclass[border=5mm]{standalone}
usepackage{tikz}
begin{document}
begin{tikzpicture}
foreach point [remember=point as p (initially {(0,0)})] in
{(1, 0), (1, 1), (0, 1)}
{
%\drawEdge{p}{point}
draw[red] p -- point circle(1mm);
}
begin{scope}[xshift=2cm]
foreach point [remember=point as p (initially {(0,1)})] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{
%\drawEdge{p}{point}
draw[blue] p -- point circle(1mm);
}
end{scope}
end{tikzpicture}
end{document}
Here is another proposal that uses a foreach
loop on all points. Not knowing what your macro is doing, I commented on his call.
Update 4 Cyclic at the request of the OP
documentclass[border=5mm]{standalone}
usepackage{tikz}
usetikzlibrary{arrows.meta}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue!75!black,thick,->,>={Straight Barb[angle=50:2pt 3]}}}
foreach point [count=n,remember=point as p (initially point)] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{ node (pointn) at point {};
}
foreach i [remember= i as lasti (initially n)]in {1,...,n}{
drawEdge{(pointlasti.center)}{(pointi.center)}
}
end{tikzpicture}
}
begin{document}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{document}
Update 3
Another possibility with the ifthen else
test:
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially point)] in
{#1}
{ ifthen {p=point} {}
{drawEdge{p}{point}}
}
end{tikzpicture}
}
begin{document}
begin{tikzpicture}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{tikzpicture}
end{document}
Second update (to answer OP's comment)
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
newcommand{drawEdges}[1]{
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially point)] in
{#1}
{
drawEdge{p}{point}
}
end{tikzpicture}
}
begin{document}
begin{tikzpicture}
drawEdges{(0,0),(1, 0), (1, 1), (0, 1)}
end{tikzpicture}
end{document}
Update
I have removed the parentheses around the parameters of your macro DrawEdge
since the foreach
loop performs an iteration on point coordinates including parentheses.
documentclass[border=5mm]{standalone}
usepackage{tikz}
newcommand{drawEdge}[2]{
draw[edgeStyle] #1 -- #2;
draw[line width = 0.1, draw=white] #1 -- #2;
}
begin{document}
begin{tikzpicture}
tikzset{edgeStyle/.style={blue,line width = 0.2}}
foreach point [remember=point as p (initially {(0,0)})] in
{(1, 0), (1, 1), (0, 1)}
{
drawEdge{p}{point}
% draw[red] p -- point circle(1mm);
}
begin{scope}[xshift=2cm]
foreach point [remember=point as p (initially {(0,1)})] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{
drawEdge{p}{point}
% draw[blue] p -- point circle(1mm);
}
end{scope}
end{tikzpicture}
end{document}
Old answer
documentclass[border=5mm]{standalone}
usepackage{tikz}
begin{document}
begin{tikzpicture}
foreach point [remember=point as p (initially {(0,0)})] in
{(1, 0), (1, 1), (0, 1)}
{
%\drawEdge{p}{point}
draw[red] p -- point circle(1mm);
}
begin{scope}[xshift=2cm]
foreach point [remember=point as p (initially {(0,1)})] in
{(0,0),(1, 0), (1, 1), (0, 1)}
{
%\drawEdge{p}{point}
draw[blue] p -- point circle(1mm);
}
end{scope}
end{tikzpicture}
end{document}
edited Dec 9 '18 at 19:50
answered Dec 9 '18 at 18:09
AndréCAndréC
8,82911447
8,82911447
How would you define the macrodrawEdges
? The difficulty seems to be in extracting the first or last point in the list, which is done manually here.
– kaba
Dec 9 '18 at 18:23
I just updated my answer
– AndréC
Dec 9 '18 at 18:37
I think the new solution draws a line from the first point to itself, which is sometimes visible when the end-points are drawn differently.
– kaba
Dec 9 '18 at 18:41
Yes, it all depends on the options of your macro. Most of the time, it doesn't trace anything at all.
– AndréC
Dec 9 '18 at 18:43
With anifthen else
test, it does not trace anything at the first iteration.
– AndréC
Dec 9 '18 at 18:49
|
show 5 more comments
How would you define the macrodrawEdges
? The difficulty seems to be in extracting the first or last point in the list, which is done manually here.
– kaba
Dec 9 '18 at 18:23
I just updated my answer
– AndréC
Dec 9 '18 at 18:37
I think the new solution draws a line from the first point to itself, which is sometimes visible when the end-points are drawn differently.
– kaba
Dec 9 '18 at 18:41
Yes, it all depends on the options of your macro. Most of the time, it doesn't trace anything at all.
– AndréC
Dec 9 '18 at 18:43
With anifthen else
test, it does not trace anything at the first iteration.
– AndréC
Dec 9 '18 at 18:49
How would you define the macro
drawEdges
? The difficulty seems to be in extracting the first or last point in the list, which is done manually here.– kaba
Dec 9 '18 at 18:23
How would you define the macro
drawEdges
? The difficulty seems to be in extracting the first or last point in the list, which is done manually here.– kaba
Dec 9 '18 at 18:23
I just updated my answer
– AndréC
Dec 9 '18 at 18:37
I just updated my answer
– AndréC
Dec 9 '18 at 18:37
I think the new solution draws a line from the first point to itself, which is sometimes visible when the end-points are drawn differently.
– kaba
Dec 9 '18 at 18:41
I think the new solution draws a line from the first point to itself, which is sometimes visible when the end-points are drawn differently.
– kaba
Dec 9 '18 at 18:41
Yes, it all depends on the options of your macro. Most of the time, it doesn't trace anything at all.
– AndréC
Dec 9 '18 at 18:43
Yes, it all depends on the options of your macro. Most of the time, it doesn't trace anything at all.
– AndréC
Dec 9 '18 at 18:43
With an
ifthen else
test, it does not trace anything at the first iteration.– AndréC
Dec 9 '18 at 18:49
With an
ifthen else
test, it does not trace anything at the first iteration.– AndréC
Dec 9 '18 at 18:49
|
show 5 more comments
If drawEdge
draws lines, then one can use plot coordinates{<coordinates>}
to achieve this.
A MWE:
documentclass[tikz,border=3mm]{standalone}
usetikzlibrary{calc}
begin{document}
begin{tikzpicture}
draw[smooth cycle,tension=0] plot coordinates{(0,0) (0,1) (1,1) (1,0)};
draw[red] plot coordinates{(0,2) (0,3) (1,3) (1,2)};
end{tikzpicture}
end{document}
Is there a difference between plot coordinates and drawing a path? Each edge should be drawn separately, so for example if the edge's style contains a decorator, then that decorator should be applied to each edge.
– kaba
Dec 9 '18 at 18:27
Your answer reminded me of the correct syntax:plot coordinates
, not justcoordinates
, +1 for that. ;-) @kaba As I mentioned in my answer at the very end, you can do all the decorations and so on, see e.g. this answer, where there is a marking decoration on each connection between two points.
– marmot
Dec 9 '18 at 18:42
add a comment |
If drawEdge
draws lines, then one can use plot coordinates{<coordinates>}
to achieve this.
A MWE:
documentclass[tikz,border=3mm]{standalone}
usetikzlibrary{calc}
begin{document}
begin{tikzpicture}
draw[smooth cycle,tension=0] plot coordinates{(0,0) (0,1) (1,1) (1,0)};
draw[red] plot coordinates{(0,2) (0,3) (1,3) (1,2)};
end{tikzpicture}
end{document}
Is there a difference between plot coordinates and drawing a path? Each edge should be drawn separately, so for example if the edge's style contains a decorator, then that decorator should be applied to each edge.
– kaba
Dec 9 '18 at 18:27
Your answer reminded me of the correct syntax:plot coordinates
, not justcoordinates
, +1 for that. ;-) @kaba As I mentioned in my answer at the very end, you can do all the decorations and so on, see e.g. this answer, where there is a marking decoration on each connection between two points.
– marmot
Dec 9 '18 at 18:42
add a comment |
If drawEdge
draws lines, then one can use plot coordinates{<coordinates>}
to achieve this.
A MWE:
documentclass[tikz,border=3mm]{standalone}
usetikzlibrary{calc}
begin{document}
begin{tikzpicture}
draw[smooth cycle,tension=0] plot coordinates{(0,0) (0,1) (1,1) (1,0)};
draw[red] plot coordinates{(0,2) (0,3) (1,3) (1,2)};
end{tikzpicture}
end{document}
If drawEdge
draws lines, then one can use plot coordinates{<coordinates>}
to achieve this.
A MWE:
documentclass[tikz,border=3mm]{standalone}
usetikzlibrary{calc}
begin{document}
begin{tikzpicture}
draw[smooth cycle,tension=0] plot coordinates{(0,0) (0,1) (1,1) (1,0)};
draw[red] plot coordinates{(0,2) (0,3) (1,3) (1,2)};
end{tikzpicture}
end{document}
answered Dec 9 '18 at 17:47
nidhinnidhin
3,3521927
3,3521927
Is there a difference between plot coordinates and drawing a path? Each edge should be drawn separately, so for example if the edge's style contains a decorator, then that decorator should be applied to each edge.
– kaba
Dec 9 '18 at 18:27
Your answer reminded me of the correct syntax:plot coordinates
, not justcoordinates
, +1 for that. ;-) @kaba As I mentioned in my answer at the very end, you can do all the decorations and so on, see e.g. this answer, where there is a marking decoration on each connection between two points.
– marmot
Dec 9 '18 at 18:42
add a comment |
Is there a difference between plot coordinates and drawing a path? Each edge should be drawn separately, so for example if the edge's style contains a decorator, then that decorator should be applied to each edge.
– kaba
Dec 9 '18 at 18:27
Your answer reminded me of the correct syntax:plot coordinates
, not justcoordinates
, +1 for that. ;-) @kaba As I mentioned in my answer at the very end, you can do all the decorations and so on, see e.g. this answer, where there is a marking decoration on each connection between two points.
– marmot
Dec 9 '18 at 18:42
Is there a difference between plot coordinates and drawing a path? Each edge should be drawn separately, so for example if the edge's style contains a decorator, then that decorator should be applied to each edge.
– kaba
Dec 9 '18 at 18:27
Is there a difference between plot coordinates and drawing a path? Each edge should be drawn separately, so for example if the edge's style contains a decorator, then that decorator should be applied to each edge.
– kaba
Dec 9 '18 at 18:27
Your answer reminded me of the correct syntax:
plot coordinates
, not just coordinates
, +1 for that. ;-) @kaba As I mentioned in my answer at the very end, you can do all the decorations and so on, see e.g. this answer, where there is a marking decoration on each connection between two points.– marmot
Dec 9 '18 at 18:42
Your answer reminded me of the correct syntax:
plot coordinates
, not just coordinates
, +1 for that. ;-) @kaba As I mentioned in my answer at the very end, you can do all the decorations and so on, see e.g. this answer, where there is a marking decoration on each connection between two points.– marmot
Dec 9 '18 at 18:42
add a comment |
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%2f463990%2ftikz-call-a-macro-between-subsequent-points-in-a-list%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