\subsection{The \emph{luadraw\_decorations} module}

The \cmd{luadraw\_decorations} module redefines certain graphics methods to add options such as adding a label, but for each of them, \textbf{the old syntax is still valid}. This module does not return anything.

\subsubsection{2D Polygonal Lines: g:Dpolyline()}

The method \cmd{g:Dpolyline(L, options)} draws the polygonal line \argu{L} (a list of complex numbers or a list of lists of complex numbers). The argument \argu{options} is an array whose fields define the possible options, which are (with their default values):
\begin{itemize}
    \item \opt{close=\false}: a boolean indicating whether the line \argu{L} should be closed.

    \item \opt{clip=\nil}: This option is either \nil (default value) or a table of the form \code{\{x1,x2,y1,y2\}}. In the first case, the row is clipped by the current 2D window \textbf{after} its transformation by the 2D matrix of the graph. In the second case, the row is clipped by the window $[x_1;x_2]\times[y_1;y_2]$ \textbf{before} being transformed by the matrix of the graph.

    \item \opt{draw\_options=\val{""}}: String (empty by default) that will be passed as is to the \drawcmd instruction.
    
    \item Options for adding a label:
    \begin{itemize}
        \item \opt{label=\val{""}}: label to add.
        
        \item \opt{anchor1d=\nil}: number between $0$ and $1$ indicating the label's position along line \argu{L} ($0$ for the beginning of the line, $1$ for the end of the line).
        
        \item \opt{anchor=\nil}: complex number representing the label's anchor point in the plane.

    \item \opt{anchor2d=\val{cpx.Z(0.5,0.5)}}: complex number representing the label's position within the bounding box $[0;1]\times[0;1]$ of line \argu{L}; therefore, by default, the label is at the center of this box.

    The order of priority is: \opt{anchor}, \opt{anchor1d}, \opt{anchor2d} (if the first option is \nil, the second is chosen; if it is also \nil, then the third is chosen).

    \item \opt{pos=\val{"center"}} indicates the label's position relative to the anchor point. It can be \val{"center"} (centered), \val{"N"} (north), \val{"NE"} (northeast), \val{"E"} (east), \val{"SE"} (southeast), \val{"S"} (south), \val{"SW"} (southwest), \val{"W"} (west), \val{"NW"} (northwest). By default, it is \val{center}, and in this case, the label is centered on the anchor point.

    \item \opt{dist=\val{0}}, the distance in cm between the label and its anchor point when \opt{pos} is not equal to \val{"center"}.

    \item \opt{dir=\val{\{\}}}, this option is a table of the form \code{\{dirX \fac{,dirY,dep}\}} which indicates the writing direction. The three values ​​\code{dirX}, \code{dirY}, and \code{dep} are three complex numbers representing three vectors. The first two indicate the writing direction, and the third indicates a displacement (translation) of the label relative to the anchor point. The vector \code{dep} is zero by default, and the vector \code{dirY}, if absent, is equal to the vector \code{dirX} rotated 90 degrees in the clockwise direction. By default, the \opt{dir} option is equal to the current writing direction.

    \item \opt{node\_options=\val{""}} is a string (empty by default) intended to receive options that will be directly passed to TikZ in the \emph{node[]} instruction.

    \item \opt{showanchor=\false}: with the value \true, the anchor point is displayed along with the label's bounding box.
    \end{itemize}
\end{itemize}


\subsubsection{2D Paths: g:Dpath()}

The method \cmd{g:Dpath(P, options)} draws path \argu{P}. The \argu{options} are the same as for the method \cmd{g:Dpolyline()} except for the options \opt{close} and \opt{clip}, which are ignored.

\subsubsection{2D Lines: g:Dline()}

The method \cmd{g:Dline(d, options)} draws the line \argu{d}, which is a list of the form $\{A,u\}$ where $A$ represents a point on the line (a complex number) and $u$ a direction vector (a non-zero complex number).

Variant: the method \cmd{g:Dline(A, B, options)} draws the line passing through the points \argu{A} and \argu{B} (two complex numbers).

In both cases, the \argu{options} are the same as for the \cmd{g:Dpolyline()} method except for the \opt{close} and \opt{clip} options which are not taken into account, and the following option:
\begin{itemize}
    \item \opt{scale=\val 1}. The option \opt{scale} (which defaults to $1$) is either a number (percentage) to vary the length of the displayed segment (from its midpoint), or an array of two numbers (percentages) \{scaleA, scaleB\} to vary the length of the displayed segment at each of its endpoints.
\end{itemize}

\subsubsection{2D Segments: g:Dseg()}

The method \cmd{g:Dseg(seg, options)} where \argu{seg}=$\{A,B\}$ with $A$ and $B$ being two complex numbers, draws the segment $[A;B]$. The \argu{options} are the same as for the method \cmd{g:Dpolyline()} except for the \opt{close} and \opt{clip} options, which are ignored, and the following two options:
\begin{itemize}
    \item \opt{scale=\val 1}. The option \opt{scale} (which defaults to $1$) is either a number (percentage) to vary the length of the displayed segment (from its midpoint), or an array of two numbers (percentages) \{scaleA, scaleB\} to vary the length of the displayed segment at each of its endpoints.
    
    \item \opt{ticks=\val{"none"}}: allows adding or removing tick marks (graduations) on the segment. The syntax for adding them is: \opt{ticks=\{nb \fac{, length, space, draw\_options}\}} where \argu{nb} is the number of strokes to add.
\end{itemize}


\subsubsection{2D Arc: g:Darc()}

The \cmd{g:Darc(B, A, C, r, direction, options)} method draws a circular arc centered at \argu{A} (a complex number), with radius \argu{r}, extending from \argu{B} (a complex number) to \argu{C} (a complex number) in the counterclockwise direction if the argument \argu{direction} is $1$, and in the opposite direction otherwise. The argument `\argu{options}` is a table whose fields define the possible options. These are (with their default values):

\begin{itemize}
    \item \opt{arc\_options=\val{""}}: string passed to the \drawcmd instruction for drawing the arc.
    \item \opt{sector\_options=\val{""}}: string defining the fill mode for the angular sector.
    \item \opt{label=\val{""}}: text to be displayed.
    \item \opt{node\_options=""}: string defining the options for the label.
    \item \opt{pos=\val{"auto"}}: specifies the label's position relative to the anchor point. Other possible values ​​are the usual values ​​for positioning a label: \val{"center"}, \val{"N"}, etc. By default, the anchor point is located at the intersection of the circular arc and the angle bisector.
    \item \opt{dist=\val{r}}: distance between the anchor point and the center of the circle; by default, this is the radius \argu{r} of the circle.
    \item \opt{angle=\val{0}}: angle (in degrees) of rotation that the anchor point should make by default around the center of the circle.
    \item \opt{rotate=\val{"none"}}: indicates whether the label should be rotated around its anchor point. Other possible values ​​are: \val{"auto"}, in which case the label is written along the angle bisector, or \val{"ortho"}, in which case the label is written perpendicular to the angle bisector.
    \item \opt{ticks=\val{"none"}}: allows you to add or not add markings (graduations) on the arc of a circle for an acute angle. The syntax for adding them is: \opt{ticks=\{nb \fac{, length, space, draw\_options}\}} where \argu{nb} is the number of lines to add.
    \item \opt{showanchor=\false}: with the value \true, the anchor point is drawn, as well as the bisector and the box around the label.
\end{itemize}

\begin{demo}{g:Darc() Method}
\begin{luadraw}{name=decoratedarc2D}
local ld = luadraw
local cpx = ld.cpx
local Z, i = cpx.Z, cpx.I

local g = ld.graph:new{window={-5,3,-3,5}, size={10,10}}
require 'luadraw_decorations'
g:Shift(Z(0,-2)) -- example 1
local b,a,c,r = 3, 0, 2.5+1.5*i, 2
g:Dpolyline({b,a,c})
g:Darc(b,a,c,r,1, {
    label="angle", rotate="auto", 
    sector_options="fill=Pink,opacity=0.5", 
    arc_options="red,line width=0.8pt,-latex"  })
g:Dlabel("Example 1",1.5,{pos="S"})
g:Shift(Z(0,4))  -- example 2     
b,a,c,r = 3, 0, 2.5+3*i, 2    
g:Dpolyline({b,a,c})
g:Darc(b,a,c,r,1, {
    label="angle", rotate="ortho", 
    sector_options="left color=white, right color=blue!50", 
    arc_options="line width=0.8pt,latex-latex",
    showanchor=true  })
g:Dlabel("Example 2",1.5,{pos="S"})
g:Shift(Z(-3.5,0))  -- example 3     
b,a,c,r = 3, 0, 1+3*i, 1.5    
g:Dpolyline({b,a,c})
g:Darc(b,a,c,r,-1, {
    label="angle", dist=r/2, pos="center",
    node_options="fill=white",
    sector_options="pattern=north west lines,pattern color=gray", 
    arc_options="line width=0.8pt,green"   })
g:Dlabel("Example 3",1.5,{pos="N"})    
g:Shift(Z(2,-4)) -- example 4
b,a,c,r = -3, 0, -1+2*i, 2    
g:Dpolyline({b,a,c})
g:Darc(b,a,c,r,-1, {
    label="angle", dist=r+0.125, 
    node_options="draw,inner sep=1pt",
    arc_options="line width=0.8pt,blue,-Stealth",
    ticks=3  })
g:Dlabel("Example 4",-1.5,{pos="S"})
g:Show()
\end{luadraw}
\end{demo}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3D

\subsubsection{3D Arc: g:Darc3d()}

The method \cmd{g:Darc3d(B, A, C, r, direction, options)} draws a circular arc centered at \argu{A} (3D point), with radius \argu{r}, extending from \argu{B} (3D point) to \argu{C} (3D point) in the clockwise direction if the argument \argu{direction} is $1$, and in the counterclockwise direction otherwise. This arc is drawn in the plane containing the three points \argu{A}, \argu{B}, and \argu{C}. When these three points are collinear, the option \opt{normal} (non-zero 3D point) must be specified, which represents a normal vector to the plane. This plane is oriented by the cross product $\vec{AB}\wedge\vec{AC}$ or by the vector \opt{normal} if specified. The argument \argu{options} is an array whose fields define the possible options, which are (with their default values):

\begin{itemize}
    \item \opt{normal=\nil}: a non-zero 3D point representing a normal vector to plane $(ABC)$. It is optional if the three points are not collinear.

    \item \opt{arc\_options=\val{""}}: a string passed to the \drawcmd instruction for drawing the arc.

    \item \opt{sector\_options=\val{""}}: a string defining the fill mode for the angular sector.

    \item \opt{label=\val{""}}: the text to be displayed.

    \item \opt{node\_options=\val{""}}: String defining the options for the label.

    \item \opt{pos=\val{"auto"}}: Specifies the label's position relative to the anchor point. Other possible values ​​are the usual values ​​for positioning a label: \val{"center"}, \val{"N"}, \val{"NW"}, etc. By default, the anchor point is located at the intersection of the arc of the circle and the angle bisector.

    \item \opt{dist=\val{r}}: Distance between the anchor point and the center of the circle ($A$). By default, this is the radius \argu{r} of the circle.

    \item \opt{angle=\val{0}}: Angle (in degrees) of rotation that the anchor point should make by default around the center of the circle ($A$) and in the plane of the circle.

    \item \opt{rotate=\val{"none"}}: indicates whether the label should be rotated around its anchor point \textbf{in the screen plane}. Other possible values ​​are: \val{"auto"}, in which case the label is written along the bisector, or \val{"ortho"}, in which case the label is written perpendicular to the bisector.

    \item \opt{rotate3d=\val{"none"}}: Indicates whether the label should be rotated around its anchor point \textbf{in the plane ($(ABC)$)}. Other possible values ​​are: \val{"auto"}, in which case the label is written along the angle bisector, or \val{"ortho"}, in which case the label is written perpendicular to the angle bisector (still in the plane $(ABC)$). With the value \val{"none"}, the label is written in the screen plane.

    \item \opt{ticks=\val{"none"}}: Allows you to add or not add markings (graduations) on the arc of a circle for an acute angle. The syntax for adding them is: \opt{ticks=\{nb \fac{, length, space, draw\_options}\}} where \argu{nb} is the number of lines to add.

    \item \opt{showanchor=\false}: With the value \true, the anchor point is drawn, along with the bisector and the box around the label.

    \item \opt{bezier=\true}: To draw the arc with Bézier curves, with the value \false, the arc is a polygonal line. When TikZ adds an arrow to the end of a Bézier curve, it undergoes a slight deformation that can create an artifact when the angular sector needs to be painted; in this case, it is better to use the \opt{bezier=\false} option.
\end{itemize}

\begin{demo}{Method \emph{g:Darc3d()}}
\begin{luadraw}{name=decorated_arcs3D}
local ld = luadraw
local pt3d = ld.pt3d
local Origin, vecI, vecJ, vecK, M = pt3d.Origin, pt3d.vecI, pt3d.vecJ, pt3d.vecK, pt3d.M

local g = ld.graph3d:new{ window={-3,8,-5,8}, viewdir={"xy",0.8,60}, size={10,10} }
require 'luadraw_decorations'
local O, P = Origin, M(6.5, 6, 4)
local Px,Pz,Py,Pxz = ld.px(P), ld.pz(P), ld.py(P), ld.pxz(P)

g:Dpolyline3d({{O, 7*vecI}, {O, 7*vecJ}, {O, 6*vecK}}, "-Stealth,solid,black, line width=1pt")
g:Dlabel3d("$x$", 7*vecI, {pos="E"}, "$y$", 7*vecJ, {pos="N"}, "$z$", 6*vecK, {pos="S"})
g:Dpolyline3d({{P,Py}, {P,Pxz}, {Pxz,Px}, {O,Pxz}, {Pxz,Pz}}, "dashed,blue,thick")
g:Dseg3d({O, P}, "-latex,RosyBrown,line width=4pt")
g:Dpolyline3d({{O, 2.5*vecI}, {O, 2.5*vecJ}, {O, 2.5*vecK}}, "-latex,cyan,line width=3pt")

g:Darc3d(Px, O, P, 4, 1, {
    arc_options = "-Stealth,blue,ultra thick",
    sector_options = "fill=blue,opacity=0.2",
    label = "$\\alpha$", node_options="blue,scale=1.25",
    rotate = "ortho", pos="N" })
     
g:Darc3d(Py, O, P, 4, 1, {
    arc_options = "-Stealth,green,ultra thick",
    sector_options = "fill=green,opacity=0.2",
    label = "$\\beta$", node_options="green,scale=1.25",
    pos = "S", rotate3d = "ortho"  }) 
     
g:Darc3d(Px, O, Pz, 4, 1, {
    arc_options = "-Stealth,Crimson,ultra thick",
    sector_options = "fill=Crimson,opacity=0.2",
    label = "$\\delta$", node_options="Crimson,scale=1.25",
    rotate3d = "auto", angle=-5,
    showanchor=true  })  

g:Darc3d(Pz, O, P, 4, 1, {
    arc_options = "-Stealth,violet,ultra thick",
    sector_options = "fill=violet,opacity=0.2",
    label = "$\\gamma$", node_options="violet,scale=1.25",
    pos="E"  }) 
g:Ddots3d({P,Pxz,Px,Py,Pz})     
g:Show()
\end{luadraw}
\end{demo}


\paragraph{Conclusion}:
\begin{enumerate}
    \item In all 2D or 3D line drawing methods that call one of the previous methods, for those that have an argument \argu{draw\_options}, which is normally a string, this can be replaced by an array \argu{options} as in the new method \cmd{g:Dpolyline(L, options)}.

    \item In all 2D or 3D line drawing methods that already have an argument \argu{options} (or \argu{args}), and that have one of these options called \opt{draw\_options}, which is normally a string, this can be replaced by an array \argu{options} as in the new method \cmd{g:Dpolyline(L, options)}.
\end{enumerate}

\begin{demo}{2D Decorations}
\begin{luadraw}{name=decorations2d}
local ld = luadraw
local cpx = ld.cpx
local Z = cpx.Z

local g = ld.graph:new{size={10,10}}
require 'luadraw_decorations'
local A, B = Z(1,4), Z(-3,1)
local C = ld.rotate(B,50,A)
local A1 = (B+C)/2
g:Dpolyline({A,B,C}, {close=true, draw_options="draw=none,fill=pink,fill opacity=0.3", 
    label="$(T)$", anchor=(A+B+C)/3, pos="E",node_options="DarkRed"})
g:Lineoptions(nil,"ForestGreen",8)
g:Dseg({A,B}, {scale=1.25,ticks=2,label="$D_1$",anchor1d=0,pos="E"})
g:Dseg({A,C}, {scale=1.25,ticks=2,label="$D_2$",anchor1d=1,pos="S"})
g:Dseg({C,B}, {scale=1.25,label="$D_3$",anchor1d=1,pos="W"})
g:Dmarkseg(B,A1,3); g:Dmarkseg(A1,C,3); g:Dangle(B,A1,A,0.25,"black,thin")
g:Dcircle({A,B,C}, {label='$(C)$', anchor1d=0, pos="E", draw_options="blue"})
g:Dmed(B,C,{label="$M_{bc}=H_a$",anchor1d=0.15,pos="N",dir=cpx.I*(C-B), draw_options="dashed,black,thin"})
g:Dcartesian( function(x) return (x/2)^2-4 end,{x={-5,5},
    draw_options={label="$C_f$", anchor2d=Z(0.5,0), pos="S", draw_options="red,line width=1.2pt"} })
g:Show()
\end{luadraw}
\end{demo}


\begin{demo}{3D Decorations}
\begin{luadraw}{name=decorations3d}
local ld = luadraw
local pt3d = ld.pt3d
local Origin, vecI, vecJ, vecK, M, Z = pt3d.Origin, pt3d.vecI, pt3d.vecJ, pt3d.vecK, pt3d.M, ld.cpx.Z

local g = ld.graph3d:new{size={10,10}}
require 'luadraw_decorations'
g:Dline3d(-5*vecI,5*vecI, {label="$x$",anchor=5*vecI,pos="S",draw_options="-stealth"},true)
g:Dline3d(-5*vecJ,5*vecJ, {label="$y$",anchor1d=1,pos="SE",draw_options="-stealth"},true)
g:Dcircle3d(Origin, 3, vecK, {label="$(C)$",anchor1d=0,pos="SE",
    dir={vecJ,-vecI}, draw_options="red,thick", node_options="red"})
local nb = 15
local H = ld.linspace(0,3,nb)
for k = 1, nb-1 do
    local z = H[k]
    local r = math.sqrt(9-z^2)
    g:Darc3d(M(0,-r,z),z*vecK,M(0,r,z),r,-1,vecK,"thin, red!30")
end
g:Dpath3d({-3*vecJ,Origin,3*vecK,3,-1,vecI,"ca",3*vecK,"l","cl"},
    "draw=none,pattern color=black!60,pattern=north west lines")
g:Dseg3d({Origin,5*vecK}, 
    {label="$z$",anchor2d=Z(0,1),pos="N",draw_options="-stealth"})   
g:Dseg3d({-3*vecJ,3*vecK}, {label="$3\\sqrt 2$\\,cm", pos="S", dir={M(0,1,1),M(0,-1,1)},
    ticks=2, draw_options="<->"}) 
g:Dseg3d({3*vecJ,3*vecK}, 
    {ticks=2, label="$3$", anchor=3*vecJ,pos="S",dir={vecJ,vecK}}) 
g:Dpath3d({-3*vecJ,Origin,3*vecJ,3,-1,vecI,"ca"}, 
    {label="$S$", anchor1d=0.5, pos="N",dist=0.15,draw_options="red,thick", node_options="red"})
g:Show()
\end{luadraw}
\end{demo}
