5

I am trying to draw arc's by calling a function instead of macro. I don't know how to pass a coordinate to a function. I tried two ways: one is passing it directly (preferred), the other is to pass its x and y coordinates separately. They all failed with "! Missing \endcsname inserted. \sp". Please tell me debug the following code. Thanks.

\documentclass[border=1cm]{standalone}
\usepackage{tikz}
\usetikzlibrary {math}
\usetikzlibrary{calc}   
\begin{document}
    \begin{tikzpicture} 
        \draw[loosely dashed] (0,0) grid [step=2] (5,5)
        \def \cpt {(1,2)}
        \draw (0.3,0.5) node [right] {cpt position coordinate = \cpt } ;
        \def \cptTwo {(4,2)+(180-30:3)}
  \tikzmath{
    function    arcStartPoint(\center, \bAngle, \eAngle, \radius)   {
    %function   arcStartPoint(\cx, \cy, \bAngle, \eAngle, \radius)  {
        coordinate \sp; % arc starting point
        \sp = \center + ({radius * cos(\bAngle)}, {radius * sin(\bAngle)});
        %\sp = (\cx, \cy) + ({radius * cos(\bAngle)}, {radius * sin(\bAngle)});
        { \draw[ultra thick, orange] (1,2) arc (\bAngle:\eAngle:\radius);   };
    };
    arcStartPoint(\cpt, -30, 30, 1);
    arcStartPoint(\cptTwo, -30, 30, 3);
  };
\end{tikzpicture}
\end{document}

The expected result is:

enter image description here

2
  • The compilation error was caused by me using a LaTex command keyword for superscript \sp as a variable name. Also, I learned that the parameters for a function can be only numerical (numbers, lengths, counters), no strings, no points, no arrays.
    – Leon Chang
    Dec 17, 2023 at 3:03
  • Since we can only pass numbers to a tikzmath function, not a \draw[options]. In this respect, it is not as flexible or general as a macro.
    – Leon Chang
    Dec 17, 2023 at 6:15

3 Answers 3

3

Try the following code:

\documentclass[border=1cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}
    \begin{tikzpicture} 
        \draw[loosely dashed] (0,0) grid [step=2] (5,5);

        % Modify the new command for drawing the arc to include color
        \newcommand{\arcStartPoint}[6]{% #1 = x coordinate, #2 = y coordinate, #3 = start angle, #4 = end angle, #5 = radius, #6 = color
            \draw[ultra thick, #6] (#1,#2) ++(#3:#5) arc (#3:#4:#5);
        }

        % Coordinates
        \coordinate (cpt) at (1,2);

        % Draw nodes for coordinate positions
        \draw (0.3,0.5) node [right] {cpt position coordinate = (1,2) } ;

        % Draw arcs with specified colors
        \arcStartPoint{1}{2}{-30}{30}{1}{orange} % Smaller arc in orange
        \arcStartPoint{1.4}{3.5}{30}{-30}{3}{red!80!black} % Larger arc in dark red
    \end{tikzpicture}
\end{document}

enter image description here

Also I tried using the function with the following:

\documentclass[border=1cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{math}
\usetikzlibrary{calc}   

\begin{document}
    \begin{tikzpicture} 
        \draw[loosely dashed] (0,0) grid [step=2] (5,5);

        % Define coordinates
        \coordinate (cpt) at (1,2);
        \coordinate (cptTwo) at ($(4,2)+(180-30:3)$);

        % Draw nodes to show positions
        \draw (0.3,0.5) node [right] {cpt position coordinate = (1,2)} ;
        \draw (3.3,0.5) node [right] {cptTwo position coordinate = (4,2)+(180-30:3)} ;

        % TikZ math function
        \tikzmath{
            function arcStartPoint(\cx, \cy, \bAngle, \eAngle, \radius) {
                {
                    \draw[ultra thick, orange] (\cx,\cy) ++(\bAngle:\radius) arc (\bAngle:\eAngle:\radius);
                };
            };
        }

        % Extract coordinates and use in function
        \pgfgetlastxy{\XCoord}{\YCoord};
        \path (cpt); \pgfgetlastxy{\XCoord}{\YCoord};
        arcStartPoint(\XCoord, \YCoord, -30, 30, 1);

        \path (cptTwo); \pgfgetlastxy{\XCoord}{\YCoord};
        arcStartPoint(\XCoord, \YCoord, -30, 30, 3);
    \end{tikzpicture}
\end{document}

Defined coordinate as \coordinate for better handling within TikZ.

Changed the arcStartPoint function so it now takes the x and y components of the coordinates separately. Before calling arcStartPoint, it extracts the x and y components of each coordinate using \pgfgetlastxy.

This runs but I can't seem to plot the arcs

3
  • 1
    Hmmm... The OP asked for a solution based on a TikZmath function, not a macro (see the q&a the linked ...)
    – Rmano
    Nov 23, 2023 at 21:20
  • 1
    Edited the answer
    – John Smith
    Nov 23, 2023 at 21:38
  • @JohnSmith I posted a modified version of your second piece of code to show the arcs below.
    – Leon Chang
    Dec 17, 2023 at 6:17
1

It seems that you cannot pass a coordinate to a function in a simple way. With separate x and y values passed to the function, however, it works:

\documentclass[border=1cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{math, calc}
\begin{document}
    \begin{tikzpicture} 
        \draw[loosely dashed] (0,0) grid[step=2] (5,5);
        \tikzmath{
            function arcSeparateCoord(\cx, \cy, \bAngle, \eAngle, \radius) {
                coordinate \start; 
                \start = (\cx*1pt,\cy*1pt) + 
                    ({\radius*cos(\bAngle)}, {\radius*sin(\bAngle)});
                {
                    \draw[ultra thick, orange] (\start) 
                        arc[start angle=\bAngle, end angle=\eAngle, 
                        radius=\radius]; 
                };
            };
            arcSeparateCoord(1, 2, -30, 30, 1);
        };
    \end{tikzpicture}
\end{document}

enter image description here

If you want to do more complicated calculations with coordinates, you should do them before passing the x and y values of the resulting coordinate to the function:

\documentclass[border=1cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{math, calc}
\begin{document}
    \begin{tikzpicture} 
        \draw[loosely dashed] (0,0) grid[step=2] (5,5);
        \tikzmath{
            function arcSeparateCoord(\cx, \cy, \bAngle, \eAngle, \radius) {
                coordinate \start; 
                \start = (\cx*1pt,\cy*1pt) + 
                    ({\radius*cos(\bAngle)}, {\radius*sin(\bAngle)});
                {
                    \draw[ultra thick, orange] (\start) 
                        arc[start angle=\bAngle, end angle=\eAngle, 
                        radius=\radius]; 
                };
            };
            coordinate \a; 
            \a = (4,2)+(180-30:3);
            arcSeparateCoord(\ax, \ay, -30, 30, 3);
        };
    \end{tikzpicture}
\end{document}

enter image description here

Note that I set (\cx*1pt,\cy*1pt) inside the function to make sure that values are parsed as pt, since the default coordinate system is in cm.

1

From Jasper's answer about cm to point conversion, I modified John's answer to show the arcs.

\documentclass[border=1cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{math}
\usetikzlibrary{calc}   
\begin{document}
    \begin{tikzpicture}[scale=1, every node/.style={draw}]
            \draw[loosely dashed] (0,0) grid [step=2] (5,5);

            % Define coordinates
            \coordinate (cpt) at (1,2);
            \coordinate (cptTwo) at ($(4,2)+(180-30:3)$);
            
            % Draw nodes to show positions
            \path (cpt); \pgfgetlastxy{\XCoord}{\YCoord};
            \pgfmathsetmacro{\xC}{\XCoord*(1pt)/(1cm)}
            \pgfmathsetmacro{\yC}{\YCoord*(1pt)/(1cm)}
            \draw (0.3,1.0) node [right] {cpt pt coordinate = (\XCoord,\YCoord)} ;
            \draw (0.3,0.5) node [right] {cpt cm coordinate = (\xC,\yC)} ;
            
            \path (cptTwo); \pgfgetlastxy{\XCoord}{\YCoord};
            \pgfmathsetmacro{\xCtwo}{\XCoord*(1pt)/(1cm)}
            \pgfmathsetmacro{\yCtwo}{\YCoord*(1pt)/(1cm)}
            % TikZ math function
            \tikzmath{
                function arcStartPoint(\cx, \cy, \bAngle, \eAngle, \radius) {
                    { \draw[ultra thick, orange!80!purple] (\cx, \cy) + 
                            (\bAngle:\radius) arc (\bAngle:\eAngle:\radius);            
                    };  
                };
                arcStartPoint(\xC, \yC, -30, 30, 1);    % must be inside \tikzmath
                arcStartPoint(\xCtwo, \yCtwo, -30, 30, 3);  % must be inside \tikzmath
            };
    \end{tikzpicture}
\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .