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

3 Answers3

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

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