% lua-tikz3dtools-doc.tex
% arara: lualatex: { options: ["-shell-escape"] }
% arara: lualatex: { options: ["-shell-escape"] }
\PassOptionsToPackage{english}{babel}
\PassOptionsToPackage{colorlinks = true}{hyperref}
\PassOptionsToPackage{margin = 1in}{geometry}
\PassOptionsToPackage{depth = 4}{bookmark}
\documentclass[12pt]{report}
\usepackage{
lua-tikz3dtools
,microtype
,babel
,fontspec
,unicode-math,
,caption
,subcaption
,xcolor
,geometry
,minted
,bookmark
,hyperref
}
\setmathfont{IBMPlexMath-Regular}
\counterwithin{figure}{section}
\counterwithin{table}{section}
\DeclareCaptionFormat{lua-tikz3dtools}{#1#2\par\noindent#3}
\captionsetup{
justification = raggedright
,singlelinecheck = false
,format = lua-tikz3dtools
}
\captionsetup[subfigure]{format=hang}
\setcounter{tocdepth}{3}
\setmainfont{Carlito}
\title{
The lua-tikz3dtools Package,\\
Version 1.0.0\\
{\small
https://github.com/Pseudonym321/TikZ-Animations/tree/master1/TikZ/lua-tikz3dtools}
}
\author{Jasper}
\date{\today}
\begin{document}
\maketitle
\tableofcontents
\chapter{Introduction}
lua-tikz3dtools is a Lua-based 3D graphics package for
Ti\textit{k}Z.
\section{What are the current capabilities of lua-tikz3dtools?}
lua-tikz3dtools can render multiple non-intersecting
triangulated mesh surfaces at once. It is also possible
to draw a plane which has been clipped by a rectangular
prism.
There are commands for drawing and labelling geometric
vectors too. Curves and surfaces can be defined using
matrix transformations.
\section{
How does lua-tikz3dtools improve on existing packages?
}
There are two significant packages for 3D artwork in
Ti\textit{k}Z: pgfplots and tikz-3dplot.
pgfplots can z-sort the faces of a single parametric
surface, but not multiple surfaces at once.
Both pgfplots and tikz-3dplot are capable of changing
the camera view, but the result is necessarily
orthographic, and the rotations are restricted to
azimuth and elevation; that is, the \(z\)-axis is always
vertical. tikz-3dplot offers useful pgfmath capabilities
for doing vector operations.
Neither pgfplots nor tikz-3dplot enable
matrix transformations. lua-tikz3dtools is built to render
multiple parametric objects at once, enable arbitrary
object orientations in non-orthographic projections,
and enable matrix transformations.
\section{Where is the package at, and where it is heading?}
The vision of the package lua-tikz3dtools is to one
day be able to render arbitrary numbers of intersecting
polygons, by clipping them with each other; this would
enable arbitrary surface intersections, without
visual artefacts. A more near term goal of
lua-tikz3dtools is to also implement an ODE
solving tool which approximates trajectories in
vector fields. I also want to add capabilities for
doing programming in Lua, instead of in pgf,
essentially replacing the pgfmath capabilities of
tikz-3dplot with faster Lua-based capabilities.
Soon there will also be proper camera culling for
projective scenes; that is, the action of not drawing
segments which are behind the viewing plane.\par
There iss no way to store macros in Lua from the \TeX\
end yet, so sometimes there is a problem with
repetition. While the geometric vectors are nice,
they are not yet rendered in 3D like the parametric
objects---I want to fix this as well.
I will also implement a way for the user to create
their own reusable Lua functions.
\chapter{Geometric Vectors}
\section{How are geometric vectors defined in lua-tikz3dtools?}
Geometric vectors are defined by two things: a
start-coordinate, and a relative displacement.
There are two classifications of geometric vectors;
there are zero vectors, and non-zero vectors.
A zero vector is represented by a small circle.
A non-zero vector is represented by a line segment
with an arrow. The endpoints of a non-zerovector
may or may not have a circle centered on the endpoint.
If there is no circle drawn, the arrow stops directly
at the endpoint. If a circle is drawn, then the arrow
tip is moved back by the circle's radius. Observe
the tips of the vectors in Figure \ref{fig:2-1-1}.
Both tips lie on the same point, despite one arrow tip
being offset by the circle's radius.
\begin{figure}
\centering
\begin{tikzpicture}
\drawvector[points = both,green]{0,0}{2,0}
\drawvector[blue]{4,0}{-2,0}
\end{tikzpicture}
\caption{The exact location of a geometric vector's tip.}
\label{fig:2-1-1}
\end{figure}
The syntax for drawing Figure \ref{fig:2-1-1} is shown in
the following code.
\begin{minted}{tex}
\begin{tikzpicture}
\drawvector[points = both,yellow]{0,0}{2,0}
\drawvector[blue]{4,0}{-2,0}
\end{tikzpicture}
\end{minted}
There are four values for the key
\mintinline{latex}{points}: \mintinline{latex}{neither},
\mintinline{latex}{behind}, \mintinline{latex}{front} and
\mintinline{latex}{both}. These tell the command
\mintinline{latex}{\drawvector} whether and where to put
circles over the endpoints. See Figure \ref{fig:2-1-2},
which uses the following code.
\begin{minted}{tex}
\begin{tikzpicture}
\drawvector[points = neither]{0,0}{0,1} % a)
\drawvector[points = behind]{1,0}{0,1} % b)
\drawvector[points = front]{2,0}{0,1} % c)
\drawvector[points = both]{3,0}{0,1} % d)
\end{tikzpicture}
\end{minted}
\begin{figure}
\centering
\begin{subfigure}{0.3\textwidth}
\centering
\begin{tikzpicture}
\drawvector[points = neither]{0,0}{0,1}
\end{tikzpicture}
\caption{\mintinline{latex}{points = neither}}
\end{subfigure}
\begin{subfigure}{0.3\textwidth}
\centering
\begin{tikzpicture}
\drawvector[points = behind]{1,0}{0,1}
\end{tikzpicture}
\caption{\mintinline{latex}{points = behind}}
\end{subfigure}\par
\begin{subfigure}{0.3\textwidth}
\centering
\begin{tikzpicture}
\drawvector[points = front]{2,0}{0,1}
\end{tikzpicture}
\caption{\mintinline{latex}{points = front}}
\end{subfigure}
\begin{subfigure}{0.3\textwidth}
\centering
\begin{tikzpicture}
\drawvector[points = both]{3,0}{0,1}
\end{tikzpicture}
\caption{\mintinline{latex}{points = both}}
\end{subfigure}
\caption{The values for the key \mintinline{latex}{points}.}
\label{fig:2-1-2}
\end{figure}
The \mintinline{latex}{\drawvector} syntax is mostly
meant for diagrams which don't use \(z\)-sorting.
Still, they can be used in some 3D still-diagrams;
for instance, these vectors connect nicely.
They will also eventually be able to be drawn flat
on planes. There is also a zero-vector command
available via \mintinline{latex}{\drawpoint}.
See Figure \ref{fig:2-1-3}, with the following code.
\begin{minted}{tex}
\begin{tikzpicture}
\drawpoint[red]{0,0}
\end{tikzpicture}
\end{minted}
\begin{figure}
\centering
\begin{tikzpicture}
\drawpoint[red]{0,0}
\end{tikzpicture}
\caption{Zero-vector}
\label{fig:2-1-3}
\end{figure}
\chapter{The Math Module}
When the user appends a parametric object to the segments
list, they must specify several attributes for the object.
In particular, when they specify the parametric equations
for the object, this is done using Lua syntax.
Specifically, the user writes Lua code into a tikz key,
and that Lua code is later \mintinline{lua}{load()}ed by
Lua. A useful feature of the lua function
\mintinline{lua}{load()} is that it allows the user to
input functions without their usual table prefix;
this means that the user can write just
\mintinline{lua}{cos()}, instead of
\mintinline{lua}{math.cos()}. lua-tikz3dtools defines a growing
handful of math operations, from elementary linear matrix
transformations to stereographic projections.
This list could always be expanded though as needs arise,
so to make it robust, I will make a way for the user to
make their own. See Chapter 1.\par
\textbf{lua-tikz3dtools uses row-vector convention!} This means that
you put the transformation on the right of the matrix
multiplication unlike with column vectors. Additionally,
\textbf{lua-tikz3dtools uses matrix-vector convention!} This means
that vectors are formatted like matrices---meaning that the
vector table is nested within a matrix table. This makes it
easier for the tools to communicate, and expains why we
need to index our functions at depth 2 instead of depth 1.
\section{The math functions.}
In addition to those provided by the math module,
these ones are also added.
\begin{itemize}
\item \mintinline{lua}{matrix_multiply(A, B)}
\item \mintinline{lua}{matrix_scale(factor, A)}
\item \mintinline{lua}{reciprocate_by_homogenous(vector)}
\item \mintinline{lua}{matrix_add(A, B)}
\item \mintinline{lua}{matrix_subtract(A, B)}
\item \mintinline{lua}{transpose(A)}
\item \mintinline{lua}{inverse(matrix)}
\item \mintinline{lua}{det(matrix)}
\item \mintinline{lua}{yrotation(angle)}
\item \mintinline{lua}{translate(x, y, z)}
\item \mintinline{lua}{xscale(scale)}
\item \mintinline{lua}{yscale(scale)}
\item \mintinline{lua}{zscale(scale)}
\item \mintinline{lua}{scale(scale)}
\item \mintinline{lua}{xrotation(angle)}
\item \mintinline{lua}{zrotation(angle)}
\item \mintinline{lua}{euler(alpha, beta, gamma)}
\item \mintinline{lua}{sphere(longitude, latitude)}
\item \mintinline{lua}{dot_product(u, v)}
\item \mintinline{lua}{cross_product(u, v)}
\item \mintinline{lua}{norm(u)}
\item \mintinline{lua}{normalize(u)}
\item \mintinline{lua}{identity_matrix()}
\item \mintinline{lua}{stereographic_projection(point)}
\end{itemize}
\chapter{Parametric Objects}
\section{How is a parametric object defined?}
Parametric objects are defined using a handful of
different pieces of information. In particular, they
use parametric functions, domain parameters and a samples
parameter for each dimension in the domain. Of course,
there are also parameters for color and such as well.
Figure \ref{fig:3-1-1} is defined by the following code:
\begin{minted}{tex}
\begin{tikzpicture}
\appendcurve[
u min = 0
,u max = {tau}
,u samples = 200
,transformation = {euler(pi/2,pi/3,pi/2)}
,x = {2*cos(u)}
,y = {2*sin(u)}
,z = {u}
,draw options = {
draw =purple
,ultra thick
,line cap = round
}
]
\appendsurface[
u min = 0
,u max = {tau}
,u samples = 36
,v min = 0
,v max = {tau}
,v samples = 36*2/3
,transformation = {euler(pi/2,pi/3,pi/2)}
,x = {2*cos(u)+sphere(u,v)[1][1]}
,y = {2*sin(u)+sphere(u,v)[1][2]}
,z = {u+sphere(u,v)[1][3]}
,draw options = {
draw = blue
,ultra thin
,line join = round
,line cap = round
}
,fill options = {
fill = green
,fill opacity = 0.7
}
]
\foreach \u in {0,...,35} {
\foreach \v in {0,...,35} {
\pgfmathsetmacro{\uscale}{2*pi/(36-1)}
\pgfmathsetmacro{\vscale}{2*pi/(36*2/3-1)}
\pgfmathsetmacro{\u}{\u*\uscale}
\pgfmathsetmacro{\v}{\v*\vscale}
\appendcurve[
u min = 0
,u max = 0.3
,u samples = 2
,transformation =
{euler(pi/2,pi/3,pi/2)}
,x = {
2 *
cos(token.get_macro("u")) +
(u + 1) *
sphere(
token.get_macro("u")
,token.get_macro("v")
)[1][1]
}
,y = {
2 *
sin(token.get_macro("u")) +
(u + 1) *
sphere(
token.get_macro("u")
,token.get_macro("v")
)[1][2]
}
,z = {
token.get_macro("u") +
(u + 1) *
sphere(
token.get_macro("u")
,token.get_macro("v")
)[1][3]
}
,draw options = {
-{Stealth[round]}
,line cap = round
,draw = black
}
]
}
}
\rendersegments
\end{tikzpicture}
\end{minted}
\begin{figure}
\centering
\begin{tikzpicture}
\appendcurve[
u min = 0
,u max = {tau}
,u samples = 200
,transformation = {euler(pi/2,pi/3,pi/2)}
,x = {2*cos(u)}
,y = {2*sin(u)}
,z = {u}
,draw options = {
draw =purple
,ultra thick
,line cap = round
}
]
\appendsurface[
u min = 0
,u max = {tau}
,u samples = 36
,v min = 0
,v max = {tau}
,v samples = 36*2/3
,transformation = {euler(pi/2,pi/3,pi/2)}
,x = {2*cos(u)+sphere(u,v)[1][1]}
,y = {2*sin(u)+sphere(u,v)[1][2]}
,z = {u+sphere(u,v)[1][3]}
,draw options = {
draw = blue
,ultra thin
,line join = round
,line cap = round
}
,fill options = {
fill = green
,fill opacity = 0.7
}
]
\foreach \u in {0,...,35} {
\foreach \v in {0,...,35} {
\pgfmathsetmacro{\uscale}{2*pi/(36-1)}
\pgfmathsetmacro{\vscale}{2*pi/(36*2/3-1)}
\pgfmathsetmacro{\u}{\u*\uscale}
\pgfmathsetmacro{\v}{\v*\vscale}
\appendcurve[
u min = 0
,u max = 0.3
,u samples = 2
,transformation =
{euler(pi/2,pi/3,pi/2)}
,x = {
2 *
cos(token.get_macro("u")) +
(u + 1) *
sphere(
token.get_macro("u")
,token.get_macro("v")
)[1][1]
}
,y = {
2 *
sin(token.get_macro("u")) +
(u + 1) *
sphere(
token.get_macro("u")
,token.get_macro("v")
)[1][2]
}
,z = {
token.get_macro("u") +
(u + 1) *
sphere(
token.get_macro("u")
,token.get_macro("v")
)[1][3]
}
,draw options = {
-{Stealth[round]}
,line cap = round
,draw = black
}
]
}
}
\rendersegments
\end{tikzpicture}
\caption{A triangulated mesh surface and a curve.}
\label{fig:3-1-1}
\end{figure}
lua-tikz3dtools is also capable of handling division by zero
without erroring. This is because the math is handled in
Lua, where division by zero doesn't error. We clip our
results to be well within the scope of the Ti\textit{z}Z
canvas. The code for Figure \ref{fig:3-1-2} is as follows.
\begin{minted}{tex}
\begin{tikzpicture}
\clip
(-\textwidth/2,-5)
rectangle
(\textwidth/2,5)
;
\pgfmathsetmacro{\angle}{0}
\let\angle\angle
\foreach \longitude in {1,...,36}{
\let\longitude\longitude
\appendcurve[
u min = 0
,u max = {pi}
,u samples = 4*45
,transformation = {euler(pi/2,pi/3,pi/6)}
,draw options = {
line cap = round
,draw = black
}
,x = {
stereographic_projection(
matrix_multiply(
sphere(
tau *
token.get_macro("longitude") /
36
,u
)
,euler(
0
,pi/2
,(2*pi/24) *
token.get_macro("angle") /
36
)
)
)[1][1]
}
,y = {
stereographic_projection(
matrix_multiply(
sphere(
tau *
token.get_macro("longitude") /
36
,u
)
,euler(
0
,pi/2
,(2*pi/24) *
token.get_macro("angle") /
36
)
)
)[1][2]
}
,z = 0*u
]
\appendcurve[
u min = 0
,u max = {pi}
,u samples = 23
,transformation = {
matrix_multiply(
euler(
0
,pi/2
,(2*pi/24) *
token.get_macro("angle") /
36
)
,euler(pi/2,pi/3,pi/6)
)
}
,draw options = {
line cap = round
,draw = black
}
,x = {
sphere(
tau *
token.get_macro("longitude") /
36
,u
)[1][1]
}
,y = {
sphere(
tau *
token.get_macro("longitude") /
36
,u
)[1][2]
}
,z = {
sphere(
tau *
token.get_macro("longitude") /
36
,u
)[1][3]
}
]
}
\foreach \latitude in {1,...,18}{
\let\latitude\latitude
\appendcurve[
u min = 0
,u max = {2*pi}
,u samples = 4*45
,transformation = {euler(pi/2,pi/3,pi/6)}
,draw options = {
line cap = round
,draw = black
}
,x = {
stereographic_projection(
matrix_multiply(
sphere(
u
,tau *
token.get_macro("latitude") /
36
)
,euler(
0
,pi/2
,(tau/24) *
token.get_macro("angle") /
36
)
)
)[1][1]
}
,y = {
stereographic_projection(
matrix_multiply(
sphere(
u
,tau *
token.get_macro("latitude") /
36
)
,euler(
0
,pi/2
,(tau/24) *
token.get_macro("angle") /
36
)
)
)[1][2]
}
,z = 0*u
]
\appendcurve[
u min = 0
,u max = {2*pi}
,u samples = 45
,transformation = {
matrix_multiply(
euler(
0
,pi/2
,(2*pi/24) *
token.get_macro("angle") /
36
)
,euler(pi/2,pi/3,pi/6)
)
}
,draw options = {
line cap = round
,draw = black
}
,x = {
sphere(
u
,tau*token.get_macro("latitude")/36
)[1][1]
}
,y = {
sphere(
u
,tau*token.get_macro("latitude")/36
)[1][2]
}
,z = {
sphere(
u
,tau*token.get_macro("latitude")/36
)[1][3]
}
]
}
\rendersegments
\end{tikzpicture}
\end{minted}
\begin{figure}
\centering
\begin{tikzpicture}
\clip
(-\textwidth/2,-5)
rectangle
(\textwidth/2,5)
;
\pgfmathsetmacro{\angle}{0}
\let\angle\angle
\foreach \longitude in {1,...,36}{
\let\longitude\longitude
\appendcurve[
u min = 0
,u max = {pi}
,u samples = 4*45
,transformation = {euler(pi/2,pi/3,pi/6)}
,draw options = {
line cap = round
,draw = black
}
,x = {
stereographic_projection(
matrix_multiply(
sphere(
tau *
token.get_macro("longitude") /
36
,u
)
,euler(
0
,pi/2
,(2*pi/24) *
token.get_macro("angle") /
36
)
)
)[1][1]
}
,y = {
stereographic_projection(
matrix_multiply(
sphere(
tau *
token.get_macro("longitude") /
36
,u
)
,euler(
0
,pi/2
,(2*pi/24) *
token.get_macro("angle") /
36
)
)
)[1][2]
}
,z = 0*u
]
\appendcurve[
u min = 0
,u max = {pi}
,u samples = 23
,transformation = {
matrix_multiply(
euler(
0
,pi/2
,(2*pi/24) *
token.get_macro("angle") /
36
)
,euler(pi/2,pi/3,pi/6)
)
}
,draw options = {
line cap = round
,draw = black
}
,x = {
sphere(
tau *
token.get_macro("longitude") /
36
,u
)[1][1]
}
,y = {
sphere(
tau *
token.get_macro("longitude") /
36
,u
)[1][2]
}
,z = {
sphere(
tau *
token.get_macro("longitude") /
36
,u
)[1][3]
}
]
}
\foreach \latitude in {1,...,18}{
\let\latitude\latitude
\appendcurve[
u min = 0
,u max = {2*pi}
,u samples = 4*45
,transformation = {euler(pi/2,pi/3,pi/6)}
,draw options = {
line cap = round
,draw = black
}
,x = {
stereographic_projection(
matrix_multiply(
sphere(
u
,tau *
token.get_macro("latitude") /
36
)
,euler(
0
,pi/2
,(tau/24) *
token.get_macro("angle") /
36
)
)
)[1][1]
}
,y = {
stereographic_projection(
matrix_multiply(
sphere(
u
,tau *
token.get_macro("latitude") /
36
)
,euler(
0
,pi/2
,(tau/24) *
token.get_macro("angle") /
36
)
)
)[1][2]
}
,z = 0*u
]
\appendcurve[
u min = 0
,u max = {2*pi}
,u samples = 45
,transformation = {
matrix_multiply(
euler(
0
,pi/2
,(2*pi/24) *
token.get_macro("angle") /
36
)
,euler(pi/2,pi/3,pi/6)
)
}
,draw options = {
line cap = round
,draw = black
}
,x = {
sphere(
u
,tau*token.get_macro("latitude")/36
)[1][1]
}
,y = {
sphere(
u
,tau*token.get_macro("latitude")/36
)[1][2]
}
,z = {
sphere(
u
,tau*token.get_macro("latitude")/36
)[1][3]
}
]
}
\rendersegments
\end{tikzpicture}
\caption{Automatic division by zero handling.}
\label{fig:3-1-2}
\end{figure}
lua-tikz3dtools is meant to be compatible with Ti\textit{k}Z, and
they are meant to be used together---at least for now.
Maybe one day lua-tikz3dtools will have enough capabilities to
do things like for loops and conditionals---\textit{at
home}. The code for Figure \ref{fig:3-1-3}, which
illustrates the use of a conditional, is given.
\begin{minted}{tex}
\begin{tikzpicture}
\clip
(-\textwidth/2,-5)
rectangle
(\textwidth/2,5)
;
\foreach[count = \c from 1] \angle in {20,40,...,80} {
\pgfmathsetmacro{\angle}{\angle*pi/180}
\let\angle\angle
\appendsurface[
u min = pi/6
,u max = 0.75*tau
,u samples = 36
,v min = 0
,v max = tau
,v samples = 36
,transformation = {euler(pi/2,pi/3,pi/6+pi)}
,draw options = {
draw = black
,line cap = round
,line join = round
}
,fill options = {
\ifnum\c=1
fill = red
\fi
\ifnum\c=2
fill = yellow
\fi
\ifnum\c=3
fill = green
\fi
\ifnum\c=4
fill = blue
\fi
,fill opacity = 0.6
}
,x = {
(1 / cos(token.get_macro("angle"))) *
cos(u) +
sqrt(
(
1 /
cos(token.get_macro("angle"))
)^2 - cos(token.get_macro("angle"))
) *
sphere(u,v)[1][1]
}
,y = {
(1 / cos(token.get_macro("angle"))) *
sin(u) +
sqrt(
(
1 /
cos(token.get_macro("angle"))
)^2 - cos(token.get_macro("angle"))
) *
sphere(u,v)[1][2]
}
,z = {
sqrt(
(
1 /
cos(token.get_macro("angle"))
)^2 - cos(token.get_macro("angle"))
) *
sphere(u,v)[1][3]
}
]
}
\rendersegments
\end{tikzpicture}
\end{minted}
\begin{figure}
\centering
\begin{tikzpicture}
\clip
(-\textwidth/2,-5)
rectangle
(\textwidth/2,5)
;
\foreach[count = \c from 1] \angle in {20,40,...,80} {
\pgfmathsetmacro{\angle}{\angle*pi/180}
\let\angle\angle
\appendsurface[
u min = pi/6
,u max = 0.75*tau
,u samples = 36
,v min = 0
,v max = tau
,v samples = 36
,transformation = {euler(pi/2,pi/3,pi/6+pi)}
,draw options = {
draw = black
,line cap = round
,line join = round
}
,fill options = {
\ifnum\c=1
fill = red
\fi
\ifnum\c=2
fill = yellow
\fi
\ifnum\c=3
fill = green
\fi
\ifnum\c=4
fill = blue
\fi
,fill opacity = 0.6
}
,x = {
(1 / cos(token.get_macro("angle"))) *
cos(u) +
sqrt(
(
1 /
cos(token.get_macro("angle"))
)^2 - cos(token.get_macro("angle"))
) *
sphere(u,v)[1][1]
}
,y = {
(1 / cos(token.get_macro("angle"))) *
sin(u) +
sqrt(
(
1 /
cos(token.get_macro("angle"))
)^2 - cos(token.get_macro("angle"))
) *
sphere(u,v)[1][2]
}
,z = {
sqrt(
(
1 /
cos(token.get_macro("angle"))
)^2 - cos(token.get_macro("angle"))
) *
sphere(u,v)[1][3]
}
]
}
\rendersegments
\end{tikzpicture}
\caption{Stereographically nested tori.}
\label{fig:3-1-3}
\end{figure}
\chapter{Clipped Subspaces}
A big focus for the future of this package is
triangle-triangle clipping, which generalizes to
polygon clipping. This dream is twofold; firstly it will
enable parametric surfaces to intersect, and secondly
it will enable intersecting plane diagrams which haven't
been achieved in full generality in tikz yet.
\section{Clipping individual planes.}
This is where the technology is at currently. We can
clip a single plane by a rectangular prism, and draw them.
Eventually, when the polygon clipping gets going, this will
evolve into a tool for graphing intersecting planes without
using approximations. The code for Figure \ref{fig:4-1-1}
is given.
\begin{minted}{tex}
\begin{tikzpicture}
\appendprism[%
a = 1
,b = 2
,c = 3
,d = 4
,x min = -1
,x max = 1
,y min = -1
,y max = 1
,z min = -1
,z max = 1
,transformation = {euler(pi/2,pi/3,pi/3)}
]
\appendplane[%
a = 1
,b = 2
,c = 3
,d = 1
,x min = -1
,x max = 1
,y min = -1
,y max = 1
,z min = -1
,z max = 1
,transformation = {euler(pi/2,pi/3,pi/3)}
]
\rendersegments
\end{tikzpicture}
\end{minted}
\begin{figure}
\centering
\begin{tikzpicture}
\appendprism[%
a = 1
,b = 2
,c = 3
,d = 4
,x min = -1
,x max = 1
,y min = -1
,y max = 1
,z min = -1
,z max = 1
,transformation = {euler(pi/2,pi/3,pi/3)}
]
\appendplane[%
a = 1
,b = 2
,c = 3
,d = 1
,x min = -1
,x max = 1
,y min = -1
,y max = 1
,z min = -1
,z max = 1
,transformation = {euler(pi/2,pi/3,pi/3)}
]
\rendersegments
\end{tikzpicture}
\caption{%
A plane which has been clipped by a rectangular
prism.
}
\label{fig:4-1-1}
\end{figure}
\end{document}