\newpage
\section{Class \tkzClass{path}}

This class was developed in response to a question posted on \code{tex.stackexchange.com} [\href{https://tex.stackexchange.com/questions/741663/fill-a-space-made-by-three-arcs/741758#741758}{fill-a-space-made-by-three-arcs}].

The concept was missing from the package, although in some cases it was possible to work around this using \TIKZ{} paths. When creating the \code{conic} class, I frequently had to manipulate tables of coordinates, so it became natural to formalize these as \code{paths}.

\directlua{
 z.O = point(0, 0)
 z.A = point(8, 0)
 z.E = z.O:rotation(2*math.pi / 3, z.A)
 z.C = z.O:rotation(-2*math.pi / 3, z.A)
 z.F, z.D, z.B = z.O:rotation(math.pi / 3, z.A, z.E, z.C)
 L.AC = line(z.A, z.C)
 L.OB = line(z.O, z.B)
 L.OD = line(z.O, z.D)
 L.CE = line(z.C, z.E)
 L.AE = line(z.A, z.E)
 L.OF = line(z.O, z.F)
 z.G = intersection(L.AC, L.OB)
 z.H = intersection(L.CE, L.OD)
 z.I = intersection(L.AE, L.OF)
 C.GA = circle(z.G, z.A)
 C.FE = circle(z.F, z.E)
 C.BA = circle(z.B, z.A)
 C.IE = circle(z.I, z.E)
 C.DE = circle(z.D, z.E)
 C.FA = circle(z.F, z.A)
 C.HE = circle(z.H, z.E)
 C.GC = circle(z.G, z.C)
 _,z.J = intersection(C.GA, C.FE)
 _,z.K = intersection(C.BA, C.IE)
 _,z.L = intersection(C.DE, C.IE)
 _,z.M = intersection(C.FA, C.HE)
 z.N = intersection(C.BA, C.HE)
 z.P = intersection(C.DE, C.GC)
 % the paths
 local nb = 40
 PA.th1 = C.IE:path(z.E, z.L, nb) + C.DE:path(z.L, z.O, nb) - C.FA:path(z.E, z.O, nb)
 PA.th2 = C.IE:path(z.G, z.A, nb) - C.FA:path(z.M, z.A, nb) - C.HE:path(z.G, z.M, nb)
 PA.th3 = C.IE:path(z.H, z.K, nb) + C.BA:path(z.K, z.C, nb) - C.GC:path(z.H, z.C, nb)
 PA.th4 = C.GA:path(z.A, z.J, nb) + C.FA:path(z.J, z.O, nb) - C.BA:path(z.A, z.O, nb)
 PA.th5 = C.HE:path(z.C, z.N, nb) + C.BA:path(z.N, z.O, nb) - C.DE:path(z.C, z.O, nb)
 PA.th6 = C.HE:path(z.I, z.E, nb) - C.DE:path(z.P, z.E, nb) - C.GA:path(z.I, z.P, nb)}
\begin{center}
  \begin{tikzpicture}[scale = .5, rotate = -30]
    \tkzGetNodes
    \tkzFillCircle[fill=yellow!20](O,A)
    \tkzDrawCircle[ultra thick,black](O,A)
    \tkzClipCircle(O,A)
    \tkzDrawCoordinates[draw,ultra thick,fill=green!15](PA.th1)
    \tkzDrawCoordinates[draw,ultra thick,fill=green!15](PA.th2)
    \tkzDrawCoordinates[draw,ultra thick,fill=blue!15](PA.th3)
    \tkzDrawCoordinates[draw,ultra thick,fill=blue!15](PA.th4)
    \tkzDrawCoordinates[draw,ultra thick,fill=red!15](PA.th5)
    \tkzDrawCoordinates[draw,ultra thick,fill=red!15](PA.th6)
    \tkzDrawCircle[ultra thick,black](O,A)
    \end{tikzpicture}
\end{center}

\begin{verbatim}

\directlua{
 z.O = point(0, 0)
 z.A = point(8, 0)
 z.E = z.O:rotation(2*math.pi / 3, z.A)
 z.C = z.O:rotation(-2*math.pi / 3, z.A)
 z.F, z.D, z.B = z.O:rotation(math.pi / 3, z.A, z.E, z.C)
 L.AC = line(z.A, z.C)
 L.OB = line(z.O, z.B)
 L.OD = line(z.O, z.D)
 L.CE = line(z.C, z.E)
 L.AE = line(z.A, z.E)
 L.OF = line(z.O, z.F)
 z.G = intersection(L.AC, L.OB)
 z.H = intersection(L.CE, L.OD)
 z.I = intersection(L.AE, L.OF)
 C.GA = circle(z.G, z.A)
 C.FE = circle(z.F, z.E)
 C.BA = circle(z.B, z.A)
 C.IE = circle(z.I, z.E)
 C.DE = circle(z.D, z.E)
 C.FA = circle(z.F, z.A)
 C.HE = circle(z.H, z.E)
 C.GC = circle(z.G, z.C)
 _,z.J = intersection(C.GA, C.FE)
 _,z.K = intersection(C.BA, C.IE)
 _,z.L = intersection(C.DE, C.IE)
 _,z.M = intersection(C.FA, C.HE)
 z.N = intersection(C.BA, C.HE)
 z.P = intersection(C.DE, C.GC)
 % the paths
 local nb = 40
 PA.th1 = C.IE:path(z.E, z.L, nb) + C.DE:path(z.L, z.O, nb) - C.FA:path(z.E, z.O, nb)
 PA.th2 = C.IE:path(z.G, z.A, nb) - C.FA:path(z.M, z.A, nb) - C.HE:path(z.G, z.M, nb)
 PA.th3 = C.IE:path(z.H, z.K, nb) + C.BA:path(z.K, z.C, nb) - C.GC:path(z.H, z.C, nb)
 PA.th4 = C.GA:path(z.A, z.J, nb) + C.FA:path(z.J, z.O, nb) - C.BA:path(z.A, z.O, nb)
 PA.th5 = C.HE:path(z.C, z.N, nb) + C.BA:path(z.N, z.O, nb) - C.DE:path(z.C, z.O, nb)
 PA.th6 = C.HE:path(z.I, z.E, nb) - C.DE:path(z.P, z.E, nb) - C.GA:path(z.I, z.P, nb)}
\begin{center}
  \begin{tikzpicture}[scale = .5, rotate = -30]
    \tkzGetNodes
    \tkzFillCircle[fill=yellow!20](O,A)
    \tkzDrawCircle[ultra thick,black](O,A)
    \tkzClipCircle(O,A)
    \tkzDrawCoordinates[draw,ultra thick,fill=green!15](PA.th1)
    \tkzDrawCoordinates[draw,ultra thick,fill=green!15](PA.th2)
    \tkzDrawCoordinates[draw,ultra thick,fill=blue!15](PA.th3)
    \tkzDrawCoordinates[draw,ultra thick,fill=blue!15](PA.th4)
    \tkzDrawCoordinates[draw,ultra thick,fill=red!15](PA.th5)
    \tkzDrawCoordinates[draw,ultra thick,fill=red!15](PA.th6)
    \tkzDrawCircle[ultra thick,black](O,A)
    \end{tikzpicture}
\end{center}

\end{verbatim}

\medskip

In addition to manually constructing paths from a list of points, you can also automatically generate paths using geometric classes. This is particularly useful when drawing arcs, segments, or interpolated curves. Currently, the following classes provide built-in methods to generate path objects:

\begin{itemize}
\item \tkzClass{line} — segment interpolation between two points See [\ref{ssub:line_path}]
\item \tkzClass{triangle} — triangle outline as a path. See [\ref{ssub:method_tkzmeth_triangle_path}]
\item \tkzClass{circle} — circular arcs between two points on the circumference See [\ref{ssub:circle_path}]
\item \tkzClass{conic} — arcs or full curves parameterized. See [\ref{ssub:conic_path}]
\end{itemize}

These methods typically return a \tkzClass{path} object with a default or user-defined number of points. For instance:

\begin{verbatim}
PA.arc = C.OA:path(z.A, z.B, 40) -- circular arc from A to B on circle OA
PA.seg = L.AB:path(10) -- line segment from A to B with 10 points
PA.tri = T.ABC:path() -- triangle outline path
PA.co = CO.EL:points(0, 1, 50) -- conic arc from t=0 to t=1
\end{verbatim}

These generated paths can be combined, reversed, filled, or used for \TIKZ{} decorations.


\subsection{Overview}

The path object represents an ordered sequence of 2D complex points, stored as TikZ-compatible strings in the form "(x,y)". It supports geometric operations such as translation, homothety, and rotation, and can be combined with other paths using Lua operator overloading.

The variable \code{PA} holds a table used to store paths. It is optional, and you are free to choose the variable name. However, using \code{PA} is a recommended convention for clarity and consistency. If you use a custom variable (e.g., Paths), you must initialize it manually. The \tkzFct{tkz-elements}{init\_elements()} function reinitializes the \code{PA} table if used.

When working with path objects—especially when several intermediate curves are involved—it is strongly recommended to use indexed names such as \code{PA.p1}, \code{PA.p2}, etc., rather than a generic name.

\begin{mybox}
\textbf{Rule — Prefer explicit, indexed names:}
Using \code{PA.p1}, \code{PA.p2}, \code{PA.result}, etc., improves clarity, avoids accidental overwriting, and ensures that all geometric data can be reset with a single call to \tkzFct{init\_elements()}.
\end{mybox}

This approach aligns with the overall philosophy of \tkzNamePack{tkz-elements}, where named tables like \code{PA}, \code{T}, \code{C}, and \code{L} are used to store structured geometric information. Indexing also helps make diagrams more readable, reproducible, and easier to debug.


It supports arithmetic operations for combining and manipulating paths, as well as geometric transformations such as translation, rotation, homothety, and reversal.

\subsection{Notes}

\begin{itemize}
\item Points are internally stored as strings like "(x,y)", and parsing is done via a utility function parse\_point.

\begin{verbatim}
local x, y = utils.parse_point("(3.5, -2)")
-- x = 3.5, y = -2.0
\end{verbatim}


\item Number formatting (e.g., for \TIKZ{} compatibility) should be handled by utils\_checknumber, assumed to be defined globally or in a utility module.

\item The class is designed to be lightweight and compatible with TikZ/LuaLaTeX workflows.

\end{itemize}





\subsection{Constructor \tkzMeth{path}{path(<list>)}}

Creates a new path.

\medskip

\texttt{Arguments: }
 \code{<list>} (optional): a Lua table containing point
        coordinates given as strings in TikZ format,
        e.g. \code{"(0,0)"}, \code{"(1,2)"}.


\begin{center}
  \begin{verbatim}
 PA.name = path(table_of_points) -- Creates a new path object.
  \end{verbatim}
\end{center}

\medskip

If no argument is provided, an empty path is created.


If data is provided, the input should be a table of points written as strings, e.g., |{ "(0,0)", "(1,0)"|, |"(1,1)" }| otherwise creates an empty path.

Here is a \tkzname{path} representing a simple triangle:

  \begin{mybox}
    \begin{verbatim}
      PA.name = path({ "(0, 0)", "(1, 0)","(1, 1)" })
      tex.print(tostring(PA.name))
    \end{verbatim}
  \end{mybox}



\subsection{Operator Overloading; metamethods}

\subsubsection{Table of metamethods}
\bgroup
  \catcode`_=12
  \small
  \captionof{table}{Methods of the class vector.}\label{path:metamethods}
  \begin{tabular}{ll}
  \toprule
   \texttt{Metamethods} & \texttt{Reference} \\
   \midrule
  \tkzMeta{path}{add(path1,path2)}   & [\ref{ssub:metamethod_add}]  \\
  \tkzMeta{path}{sub(path1,path2)}   & [\ref{ssub:metamethod_sub}]  \\
  \tkzMeta{path}{unm(path1)}         &  [\ref{ssub:metamethod_unm}]       \\
  \tkzMeta{vector}{tostring(path1)}   & [\ref{ssub:metamethod_tostring}]  \\
  \bottomrule
  \end{tabular}
\egroup

\subsubsection{Metamethod \tkzMeta{path}{add}}
\label{ssub:metamethod_add}
If p1 and p2 are two paths, we can obtain a third path with
  |p3 = p1:add(p2)|

 More easily with an operator

 \code{p3 = p1 + p2} — \textbf{Concatenation} \\
  Returns a new path by appending \code{p2} after \code{p1}.

\subsubsection{Metamethod \tkzMeta{path}{unm}}
\label{ssub:metamethod_sub}
|p2 = p1:unm()|

 More easily with an operator

  \code{-p} — \textbf{Reversal} \\
  Returns a copy of the path in reverse order.

\subsubsection{Metamethod \tkzMeta{path}{sub}}
\label{ssub:metamethod_unm}
If p1 and p2 are two paths, we can obtain a third path with
|p3 = p1:sub(p2)|

 More easily with an operator

  \code{p1 - p2} — \textbf{Subtraction} \\
  Equivalent to \code{p1 + (-p2)} (concatenates \code{p1} with the reversed \code{p2}).

\subsubsection{Metamethod \tkzMeta{path}{tostring}}
\label{ssub:metamethod_tostring}
String Representation

The \code{tostring} metamethod provides a readable form, mainly for debugging:

\begin{verbatim}
tostring(p) --> path: { (x1,y1) , (x2,y2) , ... }
\end{verbatim}



\subsection{Methods}

\bgroup
\catcode`\_ = 12
\small
\captionof{table}{Methods of the \texttt{path} class.}\label{path:methods}
\begin{tabular}{ll}
\toprule
\texttt{Method} & \texttt{Reference} \\
\midrule
\tkzMeth{path}{add\_point(z)}     & [\ref{ssub:method_tkzmeth_path_add__point}]\\
\tkzMeth{path}{get(i)}            & [\ref{ssub:method_tkzmeth_path_get}] \\
\tkzMeth{path}{copy()}            & [\ref{ssub:method_tkzmeth_path_copy}] \\
\tkzMeth{path}{count()}           & [\ref{ssub:method_tkzmeth_path_count}] \\
\tkzMeth{path}{translate(dx, dy)} & [\ref{ssub:method_tkzmeth_path_translate}] \\
\tkzMeth{path}{scale(kx, ky)}     & [\ref{ssub:path_scale}] \\
\tkzMeth{path}{homothety(pt, k)}  & [\ref{ssub:path_homothety}] \\
\tkzMeth{path}{map(fx, fy)}        & [\ref{ssub:path_map}] \\
\tkzMeth{path}{rotate(pt, an)}    & [\ref{ssub:method_tkzmeth_path_rotate}] \\
\tkzMeth{path}{close()}           & [\ref{ssub:method_tkzmeth_path_close}]\\
\tkzMeth{path}{sub(i1, i2)}       & [\ref{ssub:method_tkzmeth_path_sub_i1_i2}] \\
\tkzMeth{path}{show()}            & [\ref{ssub:method_tkzmeth_path_show}] \\
\tkzMeth{path}{add\_pair\_to\_path(z1, z2, n)} & or add\_pair  [\ref{ssub:subsubsection_name}] \\
\tkzMeth{path}{concat(sep)}       &  [\ref{ssub:path_concat}]\\
\bottomrule
\end{tabular}
\egroup



\subsubsection{Method \tkzMeth{path}{add\_point(pt,<n>)}}
\label{ssub:method_tkzmeth_path_add__point}

This method appends a point to the path.

\medskip

\textbf{Arguments:}
\begin{itemize}
  \item \code{pt}: either
  \begin{itemize}
    \item a \code{point} object, or
    \item a string representing a point coordinate, e.g. \code{"(2,3)"} or
          \code{"(1e-5,0)"}.
  \end{itemize}
  \item \code{n} (optional): number of decimal places used when formatting
        the coordinates for TikZ output.
\end{itemize}

\medskip

If \code{pt} is a string, it is parsed using \code{utils.parse\_point}.
Then the point is formatted (via \code{utils.format\_point}) and stored
in the path.

\medskip

If \code{n} is provided, the coordinates are rounded to \code{n}
decimal places before being stored in the path.
If omitted, a default formatting precision is used.

\medskip

\texttt{Note: }
The parameter \code{n} affects only the numerical representation in the
generated TikZ code. It does not modify the internal geometric
computation.

\medskip

\textbf{Examples}

\begin{tkzexample}[latex=.35\textwidth]
\directlua{
  PA.triangle = path()
  PA.triangle:add_point(point(0,0),0)
  PA.triangle:add_point(point(1,0),0)
  PA.triangle:add_point(point(1,1),0)
  tex.print(tostring(PA.triangle))
}
\end{tkzexample}

\begin{tkzexample}[latex=.35\textwidth]
\directlua{
  PA.p = path({ "(0,0)", "(1,0)", "(1,1)" })
  PA.p:add_point("(2,3)",0)
  PA.p:add_point("(1e-5,0)",5)
  tex.print(tostring(PA.p))
}
\end{tkzexample}
\subsubsection{Method \tkzMeth{path}{get(i)}}
\label{ssub:method_tkzmeth_path_get}

The method \code{get(i)} returns the i-th point stored in the path \texttt{PA.p}.

Paths in tkz-elements store their points as formatted coordinate strings
(e.g. "(1.000,2.000)") for compatibility with TikZ and for efficient
transfer from Lua to \TeX.
When \code{get(i)} is called, these coordinates are automatically converted back
into a proper Lua point object.

\medskip
\texttt{Return value: }

A point object corresponding to the i-th element of the path.

\medskip
\texttt{Errors: }

If the index is outside the valid range, an error is raised:



\subsubsection{Method \tkzMeth{path}{copy()}}
\label{ssub:method_tkzmeth_path_copy}

Returns a deep copy of the path

\begin{tkzexample}[latex=.3\textwidth]
\directlua{
  PA.p1 = path({ "(0, 0)", "(1, 0)","(1, 1)" })
  PA.p2 = PA.p1:copy()
  PA.p2:add_point(point(0, 0),0)}
\begin{tikzpicture}
  \tkzDrawCoordinates(PA.p2)
\end{tikzpicture}
\end{tkzexample}

\subsubsection{Method \tkzMeth{path}{count()}}
\label{ssub:method_tkzmeth_path_count}

Returns a deep copy of the path

\begin{tkzexample}[latex=.3\textwidth]
\directlua{
  PA.p1 = path({ "(0, 0)", "(1, 0)","(1, 1)" })
  PA.p2 = PA.p1:copy()
  PA.p2:add_point(point(0, 0),0)
  tex.print(PA.p2:count())
  }
\end{tkzexample}



\subsubsection{Method \tkzMeth{path}{translate(dx,dy)}}
\label{ssub:method_tkzmeth_path_translate}

Translates the path by a given vector \((dx,dy)\)

\begin{tkzexample}[latex=.3\textwidth]
\directlua{
  PA.p1 = path({ "(0,0)", "(1,0)", "(1,1)" })
  PA.p2 = PA.p1:translate(2,1)}
\begin{tikzpicture}
\tkzDrawCoordinates(PA.p2)
\end{tikzpicture}
\end{tkzexample}

\subsubsection{Method \tkzMeth{path}{scale(kx,ky)}}
\label{ssub:path_scale}

This method applies an anisotropic scaling to a path with respect to the origin.

\medskip

\texttt{Arguments: }
\begin{itemize}
  \item \code{kx} : horizontal scaling factor,
  \item \code{ky} : vertical scaling factor.
\end{itemize}

\medskip

\texttt{Description: }

Each point $P(x,y)$ of the path is transformed into
\[
P'(kx \cdot x,\; ky \cdot y).
\]

The transformation is performed relative to the origin $(0,0)$.

\medskip

\texttt{Returns: }

A new \code{path} object containing the scaled points.
The original path remains unchanged.

\medskip

\texttt{Example: }

\begin{verbatim}
PA.scaled = PA.original:scale(2,0.5)
\end{verbatim}

This doubles the $x$-coordinates and halves the $y$-coordinates.

\subsubsection{Method \tkzMeth{path}{homothety(k,<center>)}}
\label{ssub:path_homothety}

This method applies a uniform scaling (homothety) to a path.

\medskip

\textbf{Arguments}
\begin{itemize}
  \item \code{k} : scaling factor,
  \item \code{center} : optional reference point.
\end{itemize}

\medskip

\textbf{Change in Version 5}

The \code{center} parameter is now optional.
If omitted, the origin $(0,0)$ is used.

\medskip

\textbf{Description}

Each point $P(x,y)$ is transformed into
\[
P'(x',y') = (x_c + k(x - x_c),\; y_c + k(y - y_c)).
\]

\medskip

\textbf{Returns}

A new \code{path} object.

\subsubsection{Method \tkzMeth{path}{map(fx,<fy>)}}
\label{ssub:path_map}

This method applies a coordinate transformation to each point of the path.

\medskip

\texttt{Arguments: }
\begin{itemize}
  \item \code{fx} : Lua function applied to the $x$-coordinate,
  \item \code{fy} : optional Lua function applied to the $y$-coordinate.
\end{itemize}

If \code{fy} is omitted, the function \code{fx} is applied to both coordinates.

\medskip

\texttt{Description: }

Each point $P(x,y)$ of the path is transformed into
\[
P'(x',y')
\]
according to:
\[
x' = fx(x),
\qquad
y' = fy(y).
\]

If only one function is provided:
\[
(x,y) \mapsto (f(x), f(y)).
\]

\medskip

\texttt{Returns: }

A new \code{path} object containing the transformed points.
The original path is not modified.

\medskip

\texttt{Examples: }

Apply the same function to both coordinates:

\begin{verbatim}
PA.new = PA.old:map(math.abs)
\end{verbatim}

Apply different transformations:

\begin{verbatim}
PA.new = PA.old:map(
  function(x) return 2*x end,
  function(y) return 0.5*y end
)
\end{verbatim}

This produces the transformation
\[
(x,y) \mapsto (2x, 0.5y).
\]




\subsubsection{Method \tkzMeth{path}{rotate(pt, an)}}
\label{ssub:method_tkzmeth_path_rotate}

 Rotates the path around \(pt\) by angle \(\theta\) (radians)

\begin{tkzexample}[latex=.3\textwidth]
\directlua{
   z.O = point(1, 1)
   PA.base = path({ "(1,0)", "(2,0)", "(2,1)" })
   PA.rotated = PA.base:rotate(z.O, math.pi / 2)}
\begin{tikzpicture}
  \tkzGetNodes
  \tkzDrawCoordinates(PA.base)
  \tkzDrawCoordinates(PA.rotated)
  \tkzDrawPoint(O)
\end{tikzpicture}
\end{tkzexample}

\subsubsection{Method \tkzMeth{path}{close()}}
\label{ssub:method_tkzmeth_path_close}

Closes the path by repeating the first point at the end

\begin{tkzexample}[latex=.3\textwidth]
\directlua{
  PA.p = path({ "(0,0)", "(1,0)", "(1,1)" })
  PA.closed = PA.p:close()}
\begin{tikzpicture}
  \tkzDrawCoordinates[fill=green!20](PA.closed)
\end{tikzpicture}
\end{tkzexample}

\subsubsection{Method \tkzMeth{path}{sub(i1, i2)}}
\label{ssub:method_tkzmeth_path_sub_i1_i2}

Returns a subpath between two indices


\begin{tkzexample}[latex=.3\textwidth]
\directlua{
  PA.full = path({ "(0,0)", "(1,0)", "(1,1)", "(0,1)", "(0,0)" })
  PA.part = PA.full:sub(2, 4)}
\begin{tikzpicture}
  \tkzDrawCoordinates[fill=green!20](PA.part)
\end{tikzpicture}
\end{tkzexample}


\subsubsection{Method \tkzMeth{path}{show()}}
\label{ssub:method_tkzmeth_path_show}

Prints the path in the terminal (for debugging)

\begin{tkzexample}[latex=.45\textwidth]
\directlua{
  PA.p = path({ "(0,0)", "(1,0)", "(1,1)" })
  PA.p:show()}
\end{tkzexample}

% ADD(AM, 4.25) some complements
\subsubsection{Method \tkzMeth{path}{add\_pair\_to\_path(p, p, n)} or \tkzMeth{path}{add\_pair(p, p, n)}}
\label{ssub:subsubsection_name}
\begin{verbatim}
  path:add_pair(z1, z2, decimals)
\end{verbatim}

or equivalently:

\begin{verbatim}
 path:add_pair_to_path(z1, z2, decimals)
\end{verbatim}

\medskip
\texttt{Purpose: }

 The coordinates of \code{z1} and \code{z2} are extracted, formatted with a fixed number of decimals $n$, and combined into a string \code{"x1/y1/x2/y2"} appended to the path.
This string is then inserted into the current path table.This method appends to a \tkzname{path} object. a formatted point pair.
It is mainly used to store segments, by keeping together the coordinates of two points.

\medskip
\texttt{Arguments: }

\begin{itemize}
  \item \code{z1}, \code{z2} – points given as tables \code{\{re, im\}}.
  \item \code{decimals} (optional) – number of decimals (default: \code{5}).
\end{itemize}

\medskip
\texttt{Returns: }

Nothing (modifies the path in place).

\medskip
\texttt{Example usage: }

\begin{verbatim}
   local PA.p = path() -- empty path
   local z.A = point(1, 2)
   local z.B = point(3, 4)
   PA.p:add_pair(z.A, z.B, 2)
   -- PA.p = {"1.00/2.00/3.00/4.00"}
\end{verbatim}


\subsubsection{Method \tkzMeth{path}{concat(sep)}}
\label{ssub:path_concat}

This method returns a string obtained by concatenating all the coordinates stored
in a \tkzClass{path} object. The coordinates are joined in order using a
separator.

\medskip
Internally, a \tkzClass{path} contains an ordered Lua table of points written in
TikZ syntax, such as \verb|(x,y)|. The \tkzMeth{path}{concat} method simply
joins these entries into a single textual path.

\medskip
\texttt{Syntax: }
\begin{verbatim}
S = PA.myPath:concat(sep)
\end{verbatim}

\medskip
\texttt{Arguments: }
\begin{itemize}
  \item \code{sep} — optional string used to separate the coordinates
        (default: a single space \verb|" "|).
\end{itemize}

\medskip
\texttt{Returns: }
A Lua string containing all points of the path, separated by \code{sep}.
The resulting string is suitable for direct insertion into a TikZ path.

\texttt{Example: }

\begin{tkzexample}[code only]
\directlua{
init_elements()
local A = point(0, 0)
local B = point(2, 1)
local C = point(3, 0)
local P = path:new()
P:add_point(A)
P:add_point(B)
P:add_point(C)
local S = P:concat(" -- ")
}
\end{tkzexample}


\texttt{Usefulness: }

This method is useful when:
\begin{itemize}
  \item building TikZ paths dynamically from Lua;
  \item exporting or combining geometric paths;
  \item generating the argument of macros such as \verb|\tkzDrawPath|.
\end{itemize}


\subsubsection{Example : Director circle }
\label{ssub:director_circle}


Conics are drawn using the \tkzClass{path} tool.

\begin{minipage}{.55\textwidth}
  \begin{verbatim}
   \directlua{
    init_elements()
    z.O = point(0, 0)
    z.F1 = point(4, 1)
    z.F2 = point(-4, -1)
    z.H = point(4 * math.sqrt(2), 0)
    local a = tkz.length(z.O, z.H)
    CO.EL = conic(EL_bifocal(z.F2, z.F1, a))
    PA.curve = CO.EL:points(0, 1, 50)
    z.A = CO.EL.covertex
    T.HOA = triangle(z.H, z.O, z.A)
    z.P = T.HOA:parallelogram()
    C.OP = circle(z.O, z.P)
    z.L = C.OP:point(0.25)
    T.LJ, T.LK = CO.EL:tangent_from(z.L)
    z.J = T.LJ.pb
    z.K = T.LK.pb}
  \end{verbatim}
\end{minipage}
\begin{minipage}{.45\textwidth}
   \directlua{
    init_elements()
    z.O = point(0, 0)
    z.F1 = point(4, 1)
    z.F2 = point(-4, -1)
    z.H = point(4 * math.sqrt(2), 0)
    local a = tkz.length(z.O, z.H)
    CO.EL = conic(EL_bifocal(z.F2, z.F1, a))
    PA.curve = CO.EL:points(0, 1, 50)
    z.A = CO.EL.covertex
    T.HOA = triangle(z.H, z.O, z.A)
    z.P = T.HOA:parallelogram()
    C.OP = circle(z.O, z.P)
    z.L = C.OP:point(0.25)
    T.LJ, T.LK = CO.EL:tangent_from(z.L)
    z.J = T.LJ.pb
    z.K = T.LK.pb}
\begin{center}
  \begin{tikzpicture}[scale = .4]
   \tkzGetNodes
   \tkzDrawPoints(F1,F2,O)
   \tkzDrawCircles[teal](O,P)
   \tkzDrawPolygon(H,O,A,P)
   \tkzDrawCoordinates[smooth,cyan](PA.curve)
   \tkzDrawSegments[orange](O,P O,L L,J L,K)
   \tkzDrawPoints(F1,F2,O,H,A,P,L,J,K)
   \tkzLabelPoints(F1,F2,O,H,A,P,L,J,K)
  \end{tikzpicture}
\end{center}
\end{minipage}

\begin{verbatim}
\begin{tikzpicture}
 \tkzGetNodes
 \tkzDrawPoints(F1,F2,O)
 \tkzDrawCircles[teal](O,P)
 \tkzDrawPolygon(H,O,A,P)
 \tkzDrawCoordinates[smooth,cyan](PA.curve)
 \tkzDrawSegments[orange](O,P O,L L,J L,K)
 \tkzDrawPoints(F1,F2,O,H,A,P,L,J,K)
 \tkzLabelPoints(F1,F2,O,H,A,P,L,J,K)
\end{tikzpicture}
\end{verbatim}



\subsubsection{Classic parabola}
\label{ssub:classic_parabola}

This example moves away from the concept of Euclidean geometry, but the method used can be reused.
Here we want to draw a parabola whose axis of symmetry is parallel to the y-axis.
Knowing three of its points, we can determine the equation. The set of points for tracing the parabola is obtained using the tools provided by the \tkzClass{path} class.

\begin{minipage}{.55\textwidth}
\begin{verbatim}
\directlua{
 init_elements()
 z.a = point(1, 0)
 z.b = point(3, 2)
 z.c = point(0, 2)
 local A, B, C = parabola(z.a, z.b, z.c)

 function f(t0, t1, n)
 	local PA.tbl = path()
 	for t = t0, t1, (t1 - t0) / n do
 		local y = A * t ^ 2 + B * t + C
    local pt = point(t, y)
    PA.tbl:add_point(pt)
 	end
 	return PA.tbl
 end}
 \end{verbatim}
\end{minipage}
\begin{minipage}{.45\textwidth}
  \directlua{
   init_elements()
   z.a = point(1, 0)
   z.b = point(3, 2)
   z.c = point(0, 2)
   local A, B, C = tkz.parabola(z.a, z.b, z.c)

   function def_curve(t0, t1, n)
   local p = path()
   for t = t0,t1,(t1-t0)/n  do
       y = A*t^2+B*t +C
       pt = point(t, y)
       p:add_point(pt)
    end
    return p
   end

   PA.curve = def_curve(-1,3,100)}

  \begin{center}
    \begin{tikzpicture}
       \tkzGetNodes
       \tkzInit[xmin = -2,xmax=4,ymin =-1,ymax=6]
       \tkzDrawX\tkzDrawY
       \tkzDrawPoints[red,size=4pt](a,b,c)
      \tkzDrawCoordinates[smooth,purple](PA.curve)
    \end{tikzpicture}
  \end{center}
\end{minipage}


\begin{verbatim}
\begin{tikzpicture}
 \tkzGetNodes
 \tkzInit[xmin = -2,xmax=4,ymin =-1,ymax=6]
 \tkzDrawX\tkzDrawY
 \tkzDrawPoints[red,size=4pt](a,b,c)
 \draw[smooth] plot coordinates {%
 \directlua{tex.print(f(-1,3,100))}};
\end{tikzpicture}
\end{verbatim}

\subsection{Example with several paths}

\begin{tkzexample}[latex=.45\textwidth]
\directlua{
  z.O = point(0, 0)
  z.A = point(5, 0)
  C.OA = circle(z.O, z.A)
  z.S = C.OA.south
  C.SO = circle(z.S, z.O)
  z.B, z.C = intersection(C.OA, C.SO)
  C.BC = circle(z.B, z.C)
  z.D = intersection(C.OA, C.BC)
  C.CD = circle(z.C, z.D)

  local p1 = C.SO:path(z.C, z.B, 50)
  local p2 = C.BC:path(z.C, z.D, 50)
  local p3 = C.CD:path(z.D, z.B, 50)
  thepath = (-p1) + p2 + p3 }
\begin{tikzpicture}[scale=.5]
  \tkzGetNodes
  \tkzDrawCircles(O,A S,O)
  \tkzDrawArc(B,C)(D)
  \tkzDrawArc(C,D)(B)
  \tkzDrawCoordinates[fill = purple!20,
                      opacity=.4](thepath)
  \tkzDrawCoordinates[smooth,red,thick](thepath)
  \tkzDrawPoints(A,O,B,C,S,D)
  \tkzLabelPoints(A,B,C)
\end{tikzpicture}
\end{tkzexample}
\endinput