Graphics, Figures & Tablesnewcommand or something else?

Information and discussion about graphics, figures & tables in LaTeX documents.
Post Reply
topsquark
Posts: 71
Joined: Wed Oct 05, 2022 10:30 pm

newcommand or something else?

Post by topsquark »

First, I don't know if this is the right place to put this, and second I don't know if I'm using the right command. My apologies for both and if I need to change anything, please just let me know.

The example I'm going to post is ridiculous, but serves the purpose.

When I edit my code I usually need to do things like add temporary points and lines and colors and arrows, etc. If I have defined a new command, say, drawarrow:
\newcommand\drawarrow[3]{
\draw[#1] (#2) -- (#3);
}
then I can use it to draw a line with an arrow or not:
With arrow:
\drawarrow{->}{0,0}(1,1};

Without arrow
\drawarrow{}{0,0}{1,1};

Now, for a simple command like this, it's fine. But for a more complicated command I would like to be able to do something like what the regular codes do: \draw[->] or \draw[red] and the like. That way I can just add the new piece or not, as is most convenient.

Just to be clear: If I put in \drawarrow{red,->}{0,0}{1,1}; it will draw a red line with an arrow between the two points. I want to see if I can write the command as \drawarrow{0,0}{1,1}; instead of \drawarrow{}{0,0}{1,1}; while retaining the ability to add the extra {->} to add in if I want it.

This is getting me into library territory, I think? (I'm not sure I want to go that far at this point.)

-Dan

Code: Select all

\documentclass{article}
\usepackage{tikz}

\begin{document}

\newcommand\drawarrow[3]{
     \draw[#1] (#2) -- (#3);
}

\begin{tikzpicture}
      \drawarrow{}{0,0}{1,1};
      \drawarrow{->}{0,0}{1,-1}
      \drawarrow{blue,line width=2pt,dashed}{0,0}{2,0};
\end{tikzpicture}

\end{document}

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org

NEW: TikZ book now 40% off at Amazon.com for a short time.

rais
Posts: 419
Joined: Sun Nov 16, 2014 8:51 pm

newcommand or something else?

Post by rais »

Sounds more like `basics' ;)
The first argument can be made optional like this:

Code: Select all

\documentclass{article}
\usepackage{tikz}

\begin{document}

\newcommand\drawarrow[3][]{% note the second pair of brackets
     \draw[#1] (#2) -- (#3)
}

\begin{tikzpicture}
      \drawarrow{0,0}{1,1};
      \drawarrow[->]{0,0}{1,-1};
      \drawarrow[blue,line width=2pt,dashed]{0,0}{2,0};
\end{tikzpicture}

\end{document}
that should do what you want (note that the first argument, if given, is now surrounded by brackets, not braces). Then again, if I'd call a macro `\drawarrow', I'd let it output an arrow by default:

Code: Select all

\documentclass{article}
\usepackage{tikz}

\begin{document}

\newcommand\drawarrow[3][->]{% note the second pair of brackets
     \draw[#1] (#2) -- (#3)
}

\begin{tikzpicture}
      \drawarrow[]{0,0}{1,1};
      \drawarrow{0,0}{1,-1};
      \drawarrow[blue,line width=2pt,dashed]{0,0}{2,0};
\end{tikzpicture}

\end{document}
in which case you could still suppress the arrow tip by using an empty optional argument.

KR
Rainer
topsquark
Posts: 71
Joined: Wed Oct 05, 2022 10:30 pm

newcommand or something else?

Post by topsquark »

Thank you for the comments.

That would be fine, so long as all I'm doing in the new command is drawing. If it's a compound statement, like

Code: Select all

\newcommand\drawarrow[2]{
     \fill (#1) circle(2pt);
     \draw (#1) -- (#2);
}
the [->] isn't going to work. I can add to it the way I originally wrote it, though:

Code: Select all

\newcommand\drawarrow[3]{
      \fill (#2) circle(2pt);
     \draw[#1] (#2) -- (#3);
}
without any trouble.

Perhaps this will help to explain. What I am envisioning is something along the lines of programming \drawarrow to tell it to either plot the first point or not: \drawarrow[plotfirstpoint]{A}{B} as well as draw the line, but only draw the line if I put in \drawarrow{A}{B}.

Does this make any sense? I recognize I might be reaching a bit too far. Eventually I would like to see how a library is constructed. This is sort of a hesitant first step in that direction. (And, probably, I'm going to find out that my programming knowledge is waaaay too Medieval to do it. For now, I'd just like to see if I can mock a primitive version of it within the document or preamble.)

-Dan
rais
Posts: 419
Joined: Sun Nov 16, 2014 8:51 pm

newcommand or something else?

Post by rais »

Perhaps a scope is what you need:

Code: Select all

\documentclass{article}
\usepackage{tikz}

\newif\ifplotfirstpoint

\tikzset{%
  plotfirstpoint/.code={\plotfirstpointtrue},
  dontplotfirstpoint/.code={\plotfirstpointfalse} %just in case you need the opposite as well
}

\newcommand*\drawarrow[3][->]{% note the second pair of brackets
  \begin{scope}[#1]
    \ifplotfirstpoint
      \fill (#2) circle(2pt);
      \plotfirstpointfalse
    \fi
    \draw (#2) -- (#3);
  \end{scope}
}

\begin{document}
\begin{tikzpicture}
      \drawarrow{0,0.5}{1,1}
      \drawarrow[plotfirstpoint, red, ->]{0,-0.5}{1,-1}
      \drawarrow[plotfirstpoint, blue ,line width=2pt,dashed]{0,0}{2,0}
\end{tikzpicture}

\end{document}
KR
Rainer
topsquark
Posts: 71
Joined: Wed Oct 05, 2022 10:30 pm

newcommand or something else?

Post by topsquark »

Ooh! I haven't met the .code setting yet. I'll have to look that up. Thanks!

-Dan
topsquark
Posts: 71
Joined: Wed Oct 05, 2022 10:30 pm

newcommand or something else?

Post by topsquark »

Okay, I have something to add to this. Again, this is seriously overpowered for the task at hand. This one will draw a line between two given points and will place a dot at the initial point. What's new here is the colors: default is a black point and light gray line, but those can be changed.

Combined with the code above, we can also skip plotting the initial point if we like, but I won't post that code unless someone asks. It's a pretty straightforward combination of the two codes.

Between the two of these codes my question about how to program a new command is pretty well answered.

Thanks again, everyone!

-Dan

Code: Select all

\documentclass{article}

\usepackage{tikz}
\usepackage{pgfkeys}
\usetikzlibrary{quotes}

\begin{document}

\tikzset{
     mydotcol/.initial={black},
     mylinecol/.initial={lightgray},
     mydotcol/.default={black},
     mylinecol/.default={black},
     pics/drawpic/.style args={(#1),(#2)} {
          code={       
               \tikzset{mydotcol/.get=\mydotcol,
                        mylinecol/.get=\mylinecol
                       }
               \fill[color=\mydotcol] (#1) circle(2pt);
               \draw[color=\mylinecol] (#1) -- (#2);
          }
     }
}

\begin{tikzpicture}
     \pic[mydotcol=red,mylinecol=green] {drawpic={(0,0),(1,1)}};
     \pic {drawpic={(-1,1),(-1,-1)}};
\end{tikzpicture}

\end{document}
Post Reply