\section{Geometric Constructions}

This section groups together functions that construct geometric figures without a corresponding dedicated graphical method.

\subsection{circumcircle(), incircle()}

\begin{itemize}
    \item The function \cmd{ld.circumcircle(a, b, c)} (or \cmd{ld.circumcircle(\{a, b, c\})}), where \argu{a}, \argu{b}, and \argu{c} are three points (three complex numbers), returns the circumcircle of the triangle formed by these three points, in the form of a sequence: $C,r$, where $C$ is the center of the circle (a complex number), and $r$ is its radius.

    \item The function \cmd{ld.incircle3d(a, b, c)} (or \cmd{ld.incircle3d(\{a, b, c\})}), where \argu{a}, \argu{b}, and \argu{c} are three points (three complex numbers), returns the incircle of the triangle formed by these three points, as a sequence: $C,r$, where $C$ is the center of the circle (a complex number), and $r$ is its radius.
\end{itemize}

\subsection{cvx\_hull2d()}

The function \cmd{ld.cvx\_hull2d(L)}, where \argu{L} is a list of complex numbers, computes and returns a list of complex numbers representing the convex hull of \argu{L}.

\subsection{delaunay()}

The function \cmd{ld.delaunay(L)} where \argu{L} is a list of \textbf{distinct} complex numbers, returns a list of triangles (a triangle being a list of three complex numbers) obtained by Delaunay triangulation of the points of \argu{L} (the circumcircle of each triangle does not contain any of the other points).

\begin{demo}{Delaunay Triangulation}
\begin{luadraw}{name=delaunay}
local ld = luadraw
local g = ld.graph:new{bbox=false, pictureoptions="scale=2"}
local i = ld.cpx.I; g:Linewidth(6)
local L = {0.285+1.46*i,1.556-0.142*i,2.344+1.313*i,-2.38+1.218*i,1.548-0.624*i,
0.969+1.819*i, -0.086-2.191*i,-0.477+1.834*i,-0.904+1.322*i,-2.892+0.025*i}
local T = ld.delaunay(L) -- list of triangles
local n = #T
local num = 7 --we choose a triangle
local colors = ld.getpalette(ld.palGasFlame,n)
for k = 1, n do
    g:Dpolyline(T[k],true,'fill='..colors[k])
    end
g:Ddots(L)
g:Dcircle( {ld.circumcircle(T[num])}, "line width=0.4pt,gray,dashed" )
g:Ddots(T[num],"gray")
g:Show()
\end{luadraw}
\end{demo}

\subsection{voronoi()}

The function \cmd{ld.voronoi(L \fac{, window})}, where \argu{L} is a list of distinct complex numbers, determines the Voronoi diagram of the points in the list \argu{L}. This function returns a list of elements of the form \code{\{A,polygon\}}, where \code{A} is a point in the list \argu{L}, and \code{polygon} is a list of complex numbers representing the vertices of the cell associated with \code{A}. Thus, there is one cell for each point in \argu{L}. The cell for point \code{A} contains the points in the plane that are closer to \code{A} than to other points in \argu{L}. This function uses Delaunay triangulation. The optional argument \argu{window}, which defaults to \code{\{-5,5,-5,5\}}, is used to clip Voronoi cells that are unbounded; this window is automatically enlarged if necessary to contain all the points of \argu{L} as well as all the centers of the circles circumscribed about the Delaunay triangles (note: this does not change the 2D window of the current graph).

\begin{demo}{Voronoï diagram}
\begin{luadraw}{name=voronoi}
local ld = luadraw
local g = ld.graph:new{ bbox=true, margin={0,0,0,0}, size={10,10}}
local i = ld.cpx.I
local S = {0.285+1.46*i,1.556-0.142*i,2.344+1.313*i,-2.38+1.218*i,1.548-0.624*i,
0.969+1.819*i,-0.086-2.191*i,-0.477+1.834*i,-0.904+1.322*i,-2.892+0.025*i}
local V = ld.voronoi(S)
local colors = ld.getpalette(ld.rainbow,#V)
for k,T in ipairs(V) do
    local A, polygon = table.unpack(T)
    g:Dpolyline(polygon,true,"color=white, line width=1.2pt,fill="..colors[k])
    g:Ddots(A,"mark=x,white,scale=2,line width=1.2pt")-- A is one of the points of S
end
g:Dpolyline(ld.delaunay(S),true,"dotted,line width=0.6pt") -- Delaunay triangles
g:Show()
\end{luadraw}
\end{demo}


\subsection{line2strip()}

The function \cmd{ld.line2strip(L, width \fac{, close, ends, mode})} where \argu{L} is a list of complex numbers, or a list of lists of complex numbers, returns a path representing a "strip" calculated on \argu{L} and of width \argu{width}. The optional argument \argu{close} is a boolean that indicates whether \argu{L} should be closed (\false by default). 

The optional argument \argu{ends} specifies how the two ends of the strip are drawn. Possible values ​​are: \val{"none"}, \val{"butt"} (default), or \val{"round"}. To maintain compatibility with the older version, this argument can also take the values ​​\true (equivalent to \val{"butt"}) or \false (equivalent to \val{"none"}). 

The argument \argu{mode} can be either \val{"center"} (default value), or \val{"left"}, or \val{"right"}, in the first case the band is centered on \argu{L}, in the second case it is on the left of \argu{L}, and in the third case it is on the right of \argu{L}.

\begin{demo}{Example with \emph{line2strip}}
\begin{luadraw}{name=line2strip, exec=true}
local ld = luadraw
local g = ld.graph:new{bbox=false, bg="lightgray"}
local i = ld.cpx.I; g:Linewidth(8)
local p = {-3+3*i,-3,"l",0,3,3,1,"ca", 3+3*i,"l"}
local P = ld.path(p)  -- p is first converted to polyline
g:Setmatrix({-3+3*i,0.5,0.5*i})
local L = ld.line2strip(P,1,true)
g:Dpath(L,"Crimson,fill=Gold"); g:Dpath(p,"gray,dashed")
g:Dlabel("close=true",i,{})
g:Setmatrix({3+3*i,0.5,0.5*i})
L = ld.line2strip(P,1,false)
g:Dpath(L,"Crimson,fill=Gold"); g:Dpath(p,"gray,dashed")
g:Dlabel("close=false",i,{})
g:Setmatrix({-3-i,0.5,0.5*i})
L = ld.line2strip(P,1,false,"round","right")
g:Dpath(L,"Crimson,fill=Gold"); g:Dpath(p,"gray,dashed")
g:Dlabel('mode="right"',1.5*i,{}); g:Dlabel('ends="round"',0.5*i,{})
g:Setmatrix({3-i,0.5,0.5*i})
L = ld.line2strip(P,1,true,false,"left")
g:Dpath(L,"Crimson,fill=Gold"); g:Dpath(p,"gray,dashed")
g:Dlabel('mode="left"',1.5*i,{}); g:Dlabel("close=true",0.5*i,{})
g:Show()
\end{luadraw}
\end{demo}

\subsection{parallel\_polyline()}

The function \cmd{ld.parallel\_polyline(L, width \fac{, close})} where \argu{L} is a list of complex numbers, or a list of lists of complex numbers, returns a polygonal line parallel to \argu{L} and located at a "distance" equal to \argu{width}. The argument \argu{width} can be positive or negative to be on one side or the other of \argu{L} (this depends on the direction of traversal of \argu{L}). The optional argument \argu{close} is a boolean that indicates whether \argu{L} should be closed (\false by default).


\subsection{sss\_triangle()}

The function \cmd{ld.sss\_triangle(ab, bc, ca)}, where \argu{ab}, \argu{bc}, and \argu{ca} are three lengths, computes and returns a list of three points (3 complex numbers) $\{A,B,C\}$ forming the vertices of a direct triangle whose side lengths are the arguments, i.e., $AB=ab$, $BC=bc$, and $CA=ca$, when possible. Vertex $A$ is always the complex number $0$ and vertex $B$ is always the complex number $ab$. This triangle can be drawn with the \cmd{g:Dpolyline} method.

\subsection{sas\_triangle()}

The function \cmd{ld.sas\_triangle(ab, alpha, ca)}, where \argu{ab} and \argu{ca} are two lengths and \argu{alpha} is an angle in degrees, calculates and returns a list of three points (3 complex numbers) $\{A,B,C\}$ forming the vertices of a triangle such that $AB=ab$, $CA=ca$, and angle $(\vec{AB},\vec{AC})$ has a measure of \argu{alpha}, whenever possible. Vertex $A$ is always the complex number $0$ and vertex $B$ is always the complex number $ab$. This triangle can be drawn with the \cmd{g:Dpolyline} method.

\subsection{asa\_triangle()}

The function \cmd{ld.asa\_triangle(alpha, ab, beta)}, where \argu{ab} is a length, \argu{alpha} and \argu{beta} are two angles in degrees, calculates and returns a list of three points (3 complex numbers) $\{A,B,C\}$ forming the vertices of a triangle such that $AB=ab$, such that angle $(\vec{AB},\vec{AC})$ has measure \argu{alpha}, and such that angle $(\vec{BA},\vec{BC})$ has measure \argu{beta}, whenever possible. Vertex $A$ is always the complex number $0$ and vertex $B$ is always the complex number $ab$.  This triangle can be drawn using the \cmd{g:Dpolyline} method.

\begin{demo}{sss\_triangle, sas\_triangle and asa\_triangle}
\begin{luadraw}{name=sss_triangles_and_co}
local ld = luadraw
local g = ld.graph:new{window={-5,5,-3,5},size={10,10}}
g:Labelsize("footnotesize"); g:Linewidth(8)
local Zp, i, deg = ld.cpx.Zp, ld.cpx.I, ld.deg
local T1 = ld.shift( ld.sss_triangle(4,5,3), 2*i-2)
local T2 = ld.shift( ld.sas_triangle(4,60,2), -4-2*i)
local T3 = ld.shift( ld.asa_triangle(30,4,50), 0.5-i)
g:Dpolyline({T1,T2,T3}, true)
g:Linewidth(4)
g:Darc(T2[2],T2[1],T2[3],0.5,1,"->")
g:Darc(T3[2],T3[1],T3[3],0.75,1,"->")
g:Darc(T3[1],T3[2],T3[3],0.75,-1,"->")
g:Dlabel(
  "$4$",(T1[1]+T1[2])/2,{pos="N"}, "$5$",(T1[2]+T1[3])/2,{pos="NE"},"$3$",(T1[1]+T1[3])/2,{pos="W"},
  "$4$",(T2[1]+T2[2])/2,{pos="N"},"$60^\\circ$", T2[1]+Zp(0.9,30*deg),{pos="center"}, 
  "$2$",(T2[1]+T2[3])/2,{pos="W"},
  "$4$",(T3[1]+T3[2])/2,{pos="N"}, "$30^\\circ$",T3[1]+Zp(1.15,15*deg),{pos="center"},
  "$50^\\circ$",T3[2]+Zp(1.15,155*deg),{pos="center"},
  "sss\\_triangle(4,5,3)",(T1[1]+T1[2])/2,{pos="S"}, "sas\\_triangle(4,60,2)",(T2[1]+T2[2])/2,{},
  "asa\\_triangle(30,4,50)",(T3[1]+T3[2])/2,{})
for _,T in ipairs({T1,T2,T3}) do
    g:Dlabel("$A$",T[1],{pos="SW"}, "$B$",T[2],{pos="SE"},"$C$",T[3],{pos="N"})
end
g:Show()
\end{luadraw}
\end{demo}
