\documentclass[letterpaper]{article}

\usepackage{microtype}
\usepackage{mathtools}
\usepackage{unicode-math}
\usepackage{booktabs}

\usepackage{lua-tikz3dtools}

\title{lua-tikz3dtools documentation v3.3.0}
\author{Jasper Nice}
\date{2026-05-24}

\begin{document}

\maketitle
\tableofcontents

\section{Introduction}

Hi! My name is Jasper, and before I get started with this manual,
I wanted to share a bit about where it came from, and where it is going.
This is because, like anyone, I make mistakes, and I made quite a few 
here along the way. I want to acknowledge that openly, so no one is misled,
and so that people can have the greatest benefit from this. 

Much of the mistakes were the byproduct of a premature release of the 
software before it was complete. I have now finished what I believe are the 
core components of the software. I'm sorry for having the incomplete work up for so long. 

I'd really recommend taking a look at the packages luadraw, or Asymptore 
if anyone is interested in a contemporary \LaTeX{} 3D illustration softwares.

This package---lua-tikz3dtools---is geared strongly towards expressing 
everything in terms of parametric affine/projective algebra.
Sounds fancy, but it is really the backbone of a lot of seemingly incoherent
elements.

For instance, rotation, translation, perspective, shearing, and reflection 
are all projective transformations. And they can be composed!

Of course, everything eventually boils down to affine algebra after the 
transformations, as they map affine space onto itself, resulting in 
affine-workable byproducts. This is a bit abstract, but it is the reason
you can look at a perspective picture on your screen, while your screen never 
changes its basis (orientation, direction, size, and shape).

This package also takes care of occlusion and partitioning, with results 
akin to those of a BSP tree.

\section{Command reference}

\subsection{ltdtappendlabel}
This command appends a label. Its keys are 
\begin{itemize}
    \item v: a homogeneous 3D vector (e.g., 
    \verb|Vector:new{1,2,3,1}|).
    \item text: a \LaTeX{} label (e.g., \verb|\LaTeX|).
    \item transformation: A homogeneous 3D transformation matrix.
    \item filter: A boolean on v.
\end{itemize}
\begin{figure}
\centering
\begin{tikzpicture}
    \ltdtappendlabel[
        v={return Vector:new{0,0,0,1}},
        text={\LaTeX},
        transformation={return Matrix.identity()},
        filter={return A[1]<10}% true
    ]
    \draw (-1,-1) rectangle (1,1);
    \ltdtdisplaysimplices
\end{tikzpicture}
\caption{ltdtappendlabel}
\end{figure}

\subsection{ltdtappendlight}
This command appends a light direction. I recommend using only one light 
direction, unless you have a good reason not to.
\begin{itemize}
    \item v: a homogeneous 3D vector
\end{itemize}
\begin{figure}
\centering
\begin{tikzpicture}
    \ltdtappendlight[
        v={return Vector:new{1,1,1,1}}
    ]
    \ltdtappendsurface[
        v={return Vector.sphere(Vector:new{u,v,2})},
        transformation={return Matrix.zyzrotation(Vector:new{pi/6,pi/3,pi/2})},
        fill options={return "fill=ltdtbrightness,fill opacity=0.7"},
        uparams={return Vector:new{0,tau,10}},
        vparams={return Vector:new{0,pi,7}}
    ]
    \ltdtdisplaysimplices
\end{tikzpicture}
\caption{ltdtappendlight}
\end{figure}

\subsection{ltdtappendcurve}
This command appends a curve.
\begin{itemize}
    \item uparams: A 3-vector of start, stop and step in u
    \item v: a homogeneous 3D vector
    \item transformation: A homogeneous 3D transformation matrix.
    \item draw options: a string of Ti\textit{k}Z options for a path.
    \item arrow tip: a string of Ti\textit{k}Z options for a path.
    \item arrow scale: a number to change the arrow's size
    \item filter: A boolean on v.
\end{itemize}
\begin{figure}
\centering
\begin{tikzpicture}
    \ltdtappendcurve[
        v={return Vector.sphere(Vector:new{u,u,2})},
        transformation={return Matrix.zyzrotation(Vector:new{pi/6,pi/3,pi/2})},
        draw options={return "draw"},
        uparams={return Vector:new{0,tau,30}},
    ]
    \ltdtdisplaysimplices
\end{tikzpicture}
\caption{ltdtappendcurve}
\end{figure}

\subsection{ltdtappendsurface}
This command appends a surface.
\begin{itemize}
    \item uparams: A 3-vector of start, stop and step in u
    \item vparams: A 3-vector of start, stop and step in v
    \item v: a homogeneous 3D vector
    \item transformation: A homogeneous 3D transformation matrix.
    \item fill options: a string of Ti\textit{k}Z options for a path.
    \item filter: A boolean on v.
    \item curve: If you know what you're doing, you can embed a table of UV
    line segments within a surface's simplices. See the example below.
\end{itemize}
\begin{figure}
\centering
\begin{tikzpicture}
    \ltdtappendlight[
        v={return Vector:new{1,1,1,1}}
    ]
    \ltdtappendsurface[
        v={return Vector.sphere(Vector:new{u,v,1}):hadd(Vector:new{2*cos(u),2*sin(u),0,1})},
        transformation={return Matrix.zyzrotation(Vector:new{pi/6,pi/3,pi/2})},
        fill options={return "fill=ltdtbrightness,fill opacity=0.7"},
        uparams={return Vector:new{0,tau,10}},
        vparams={return Vector:new{0,tau,7}},
        curve={
            local tab = {}
            for i = 0, 60 do 
                table.insert(tab, 
                    {
                        Vector:new{i/10, i/10}, 
                        Vector:new{(i+1)/10, (i+1)/10},
                        drawoptions="draw=green"
                    }
                )
            end
            return tab
        }
    ]
    \ltdtdisplaysimplices
\end{tikzpicture}
\caption{ltdtappendsurface}
\end{figure}

\subsection{ltdtappendtriangle}
This command appends a triangle.
\begin{itemize}
    \item m: A 3-vector of start, stop and step in u
    \item transformation: A homogeneous 3D transformation matrix.
    \item fill options: a string of Ti\textit{k}Z options for a path.
    \item filter: A boolean on m.
\end{itemize}
\begin{figure}
\centering
\begin{tikzpicture}
    \ltdtappendtriangle[
        m={return Matrix:new{
            {1,1,1,1},
            {0,0,0,1},
            {-1,2,-2,1}
        }},
        fill options={return "fill=red"},
        transformation={return Matrix.zyzrotation(Vector:new{pi/6,pi/3,pi/2})}
    ]
    \ltdtdisplaysimplices
\end{tikzpicture}
\caption{ltdtappendtriangle}
\end{figure}

\subsection{ltdtappendsolid}
This command appends the surface boundaries of a solid mapped from a cube.
\begin{itemize}
    \item uparams: A 3-vector of start, stop and step in u
    \item vparams: A 3-vector of start, stop and step in v
    \item wparams: A 3-vector of start, stop and step in w
    \item v: a homogeneous 3D vector
    \item transformation: A homogeneous 3D transformation matrix.
    \item fill options: a string of Ti\textit{k}Z options for a path.
    \item filter: A boolean on v.
\end{itemize}
\begin{figure}
\centering
\begin{tikzpicture}
    \ltdtappendlight[
        v={return Vector:new{1,1,1,1}}
    ]
    \ltdtappendsolid[
        v={return Vector:new{u,v,w-v}},
        transformation={return Matrix.zyzrotation(Vector:new{pi/6,pi/3,pi/2})},
        fill options={return "fill=ltdtbrightness,fill opacity=0.7"},
        uparams={return Vector:new{0,1,10}},
        vparams={return Vector:new{0,1,7}},
        wparams={return Vector:new{0,1,7}}
    ]
    \ltdtdisplaysimplices
\end{tikzpicture}
\caption{ltdtappendsurface}
\end{figure}

\subsection{ltdtdisplaysimplices}
This command resolves the appended simplices, and displays the resulting 
output.

\subsection{ltdtsetobject}
This command sets a lua object
\begin{itemize}
    \item name: the lua name of the object.
    \item object: the lua object (e.g., a function, or a matrix).
\end{itemize}

\end{document}