We originally latched onto the ideas behind the Escherization paper
[Kaplan and Salesin2000], which introduced some ideas on how
to do computer generated tessellations given some arbitrary shape.
Given a shape, the described algorithm attempts to deform some ninety
different isohedral shapes, which comprise the different classes of
tilable shapes, into a reasonable approximation of the original shape.
The different classes of isohedral polygons also are parameterized to
determine the proper tiling pattern. While the Escherization method
sounded applicable to the Cookie Cutter problem, we eventually decided
that we would not be able to reimplement this algorithm within our
time constraints. Moreover, the Escherization method clearly states
that it works best for convex shapes, which only represented a subset
of the total possible cookie shapes we potentially had to deal with.
However, we derived an important concept from the Escherization paper.
The paper showed how the deformation of a regular polygon really equated
to a ``give and take'' on its edges. A pull on one edge of the polygon
would be complemented by a push on another edge. We believe that the
convex and concave corners of the given shape represented the result of
this sort of force and feedback equilibrium. Joining the complementing
corners of two copies of a cookie shape should reduce the entropy. To
take advantage of this, we needed to be able to measure the potential
effects of joining a particular concave corner to a convex one or vice
versa.
Our first real implementation of FFA matched convex and concave corners
whose sum of angles were near . We realized that this
lead to situations where the arm lengths of one corner did not match the
arm lengths of the other corner. Thus, the two cookie copies did not
fit well with each other, and overall, the placement of all the cookie
copies seems less than optimal.
Eventually, we struck upon another idea which runs along a similiar line of thinking behind the Slab Allocator [Bonwick1994] which minimizes the internal fragmentation in a hard drive file system. In short, the Slab Allocator allocates slabs of limited size to store files of certain sizes. By cleverly choosing the slab sizes, the Allocator can ensure speedy file access and only a certain portion of free space is wasted due to internal fragmentation. FFA follows suit by predetermining whether matching a pair of convex and concave corners will result in excessive internal fragmentation between the corners. Essentially, the FFA player compares the area of the triangle composed of the vertices from the convex corner and the other triangle formed from the vertices of the concave corner. Running this procedure over every pairwise combination of corners should result in a pair of convex and concave corners which have minimal wasted area when joined together.
Once FFA has determined which corners to join, we must compute the angle of
rotation to bring corner, , on to corner,
, where
.
![]() |
(3) |
![]() |
(4) |
Eq. 3 represents how the bisector, , is computed for corner,
,
which has arm vectors,
and
. Eq. 4 shows how FFA computes
the angle of rotation between corners,
and
. In Figure 1,
if
is matched with
,
. Thus, a copy of the
concave shape in Figure 1 will not have to rotate to join corners
and
. Once the FFA has rotated
towards
, FFA translates
the cookie which contains
such that both corners lie on top of one
another. Finally, while the two cookie overlap, the cookie containing
is translated away the other cookie in the direction of
.