Project: ArangoDB (App Definition and Development / Database)
File: GTL_boostcon2009.pdf

Geometry Template Library for STL-like 2D Operation s 
Lucanus Simonson 
Intel Corporation 
2200 Mission College Blvd. 
Santa Clara, CA 95054-1549 
1 (408) 765-8080 
lucanus.j.simonson@intel.com Gyuszi Suto 
Intel Corporation 
2200 Mission College Blvd. 
Santa Clara, CA 95054-1549 
1 (408) 765-8080 
gyuszi.suto@intel.com 
  
ABSTRACT  
There is a proliferation of geometric algorithms an d data types 
with no existing mechanism to unify geometric progr amming in 
C++.  The geometry template library (GTL) provides geometry 
concepts and concept mapping through traits as well  as algorithms 
parameterized by conceptual geometric data type to provide a 
unified library of fundamental geometric algorithms  that is 
interoperable with existing geometric data types wi thout the need 
for data copy conversion.  Specific concepts and al gorithms 
provided in GTL focus on high performance/capacity 2D polygon 
manipulation, especially polygon clipping.  The app lication-
programming interface (API) for invoking algorithms  is based on 
overloading of generic free functions by concepts.  Overloaded 
generic operator syntax for polygon clipping Boolea ns (see Figure 
1) and the supporting operator templates are provid ed to make the 
API highly productive and abstract away the details  of algorithms 
from their usage.  The library was implemented in I ntel 
Corporation to converge the programming of geometri c 
manipulations in C++ while providing best in class runtime and 
memory performance for Booleans operations.  This p aper 
discusses the specific needs of generic geometry pr ogramming 
and how those needs are met by the concepts-based t ype system 
that makes the generic API possible.  
Categories and Subject Descriptors  
I.3.5 [ Computer Graphics ]: Computational Geometry and Object 
Modeling – Curve, surface, solid and object representations.  
General Terms  
Algorithms, Performance, Design, Reliability, Stand ardization. 
Keywords  
C++ concepts, geometry, polygon clipping, data mode ling, library 
design. 
1.  INTRODUCTION 
1.1  Problem Statement and Motivation 
Traditional object-oriented design leads to type sy stems that employ a common base class to integrate new types i nto an 
existing system.  This leads to monolithic software  design with 
shared dependencies on the base class, creating bar riers of 
incompatibility between different software systems when they 
cannot share a common base class.  Integrating libr ary 
functionality into such a software system typically  requires 
wrapping the library API with functions that perfor m implicit data 
copy conversion or that data copy conversion be per formed as an 
explicit step before the library API can be used.  This leads to 
code and memory bloat in applications and to librar ies that are 
hard to use.  The problem presents itself clearly i n geometry.  An 
application will model objects that have a geometri c nature as 
well as application-specific attributes such as nam es, weights, 
colors etc.  These object models are geometric enti ties, but are 
typically not syntactically compatible with a geome tric library 
unless there is code coupling through some base geo metric class.  
Often an unnecessary copy conversion of data model to geometric 
object is required to satisfy syntactic requirement s of a geometry 
library API.  For example, to use CGAL [8] library algorithms a 
polygon that depends on CGAL header files must be d eclared and 
data copied into it before that data can be passed into the 
algorithm.  Eliminating this artificial incompatibi lity and allowing 
a geometry library’s API to be used directly and no n-intrusively in 
an application with its native object model is the design goal for 
GTL’s interfaces.  This allows application level pr ogramming 
tasks to benefit from the thoughtful design of a pr oductive and 
intuitive set of library APIs. 
1.2  C++ Concepts Address the Problem 
Computational geometry is the ideal domain to apply  C++ 
Concepts [10] based library design.  At a conceptua l level, 
geometric objects are universally understood.  Exis ting geometry 
codes coming from different sources are not inter-c ompatible due 
largely to syntactic rather than semantic differenc es.  These 
syntactic differences can be easily resolved by con cept mapping 
through C++ traits.  However, there are minor seman tic 
differences that need to be comprehended in order t o implement a 
truly generic geometry concept.  
Permission to make digital or hard copies of all or  part of this work for 
personal or classroom use is granted without fee pr ovided that copies are 
not made or distributed for profit or commercial ad vantage and that 
copies bear this notice and the full citation on th e first page. To copy 
otherwise, or republish, to post on servers or to r edistribute to lists, 
requires prior specific permission and/or a fee. 
Boostcon’09 , May 3–8, 2009, Aspen, Colorado, USA. 
Copyright 2009 ACM 1-58113-000-0/00/0004…$5.00. 
 
Figure 1. Booleans example: disjoint-union (a xor b ) is c. A generic geometry library must also parameterize t he 
numerical coordinate data type while at the same ti me providing 
numerically robust arithmetic.  Doing this requires  more than 
simply making the coordinate data type a template p arameter 
everywhere, but also looking up parameterized coord inate type 
conversions, handling the differences between integ er and floating 
point programming, and making sparing use of high-p recision 
data types to allow robust calculations.  The gener ic geometry 
library must define a type system of concepts that includes a 
coordinate concept and provide an API based upon it  that is both 
intuitive and productive to use yet maintainable an d easily 
extensible.   
We will compare and contrast different proposed app roaches 
to generic geometry type systems in Section 2.  Sec tion 3 will 
present the approach used in GTL to implement a geo metry 
concepts API and explain its advantages over other proposals.  
Operator templates and the details of the operator based API for 
polygon set operations (intersection, union, etc.) will be presented 
in Section 4.  In Section 5 we will present a gener ic sweep-line 
algorithmic framework, explain the principles behin d our 
implementation of sweep-line and how they are refle cted in the 
requirements placed on its template parameters.  Nu merical issues 
faced and solutions for numerical robustness proble ms 
implemented in our library will be discussed in Sec tion 6.  A 
performance comparison with several open source com putational 
geometry libraries will be presented in Section 7 a nd closing 
remarks in Section 8. 
2.  Generic Geometry Approaches 
There are several well known generic programming te chniques 
that are applicable to the design of a generic geom etry library 
API.  The most important is C++ traits, which provi des the 
necessary abstraction between the interface of a ge ometry object 
and its use in generic code.  In combination with t raits, other 
generic programming techniques have been proposed i n the 
design of generic geometry libraries including: tag  dispatching, 
static asserts and substitution-failure-is-not-an-e rror (SFINAE) 
template function overloading.   
2.1  Free Functions and Traits 
The conventional way to implement a generic API is with 
template functions declared within a namespace.  Th is allows 
arbitrary objects to be passed directly into templa te functions and 
accessed through their associated traits.  There is , however, one 
problem with this approach when used for computatio nal 
geometry.  How to specify what kind of geometric en tity a given 
template parameter represents?  The simplest soluti on is to name 
the function such that it is clear what kind of geo metry it expects.  
This prevents generic function name collisions and documents 
what expectation is placed upon the template parame ter.  
However, it leads to overly long function names, pa rticularly if 
two or more kinds of geometry are arguments of a fu nction.  Such 
generic functions do not lend themselves to generic  programming 
at a higher level of abstraction.  Consider the center(T)  
function.  If we name it variously rectangle_center(T)  for 
the rectangle case and polygon_center(T)  for polygons we 
cannot abstract away what kind of geometry we are d ealing with 
when working with their center points.  As an examp le, a generic 
library function that computes the centroid of an i terator range 
over geometry objects using their center points wei ghted by their area would require two definitions that differ only  by the names of 
functions that compute center and area.  As we add triangle and 
polygon-with-holes and circle to the generic librar y, the drawback 
of not being able to abstract away what kind of geo metry is being 
worked with in library code as well as user code be comes 
painfully obvious. 
2.2  Concepts and Static Assert 
A static assert generates a syntax error whenever a  concept check 
fails.  A boost geometry library proposal from Bran don Kohn [5] 
employs boost::static_assert  on top of generic free 
functions and traits.  This approach to C++ concept s when applied 
to computational geometry improves the API primaril y by 
producing more intelligible syntax errors when the wrong type is 
passed into an API.  It does not solve the problem of not being 
able to abstract away the geometric concept itself because it still 
relies on functions having different names for diff erent concepts 
to prevent function name collisions. 
2.3  Tag Dispatching Based Concepts 
A series of boost geometry library proposals from B arend Gehrels 
and Bruno Lalande [2] have culminated into a tag di spatching 
based API where a generic free function that looks up tag types 
for the objects passed in to disambiguate otherwise  identical 
dispatch functions.  These dispatch functions are w rapped in 
structs to emulate partial specialization of dispat ch functions by 
specializing the struct.  Partial specialization of  template functions 
is not legal C++ syntax under the C++03 standard.   
 
This approach solves the name collision problem.  I t allows 
one center()  function, for example, to dispatch to different 
implementations for various rectangle, circle, poly gon conceptual 
types and abstract the concept away when working wi th objects 
that share the characteristic that they have a cent er.  However, it is 
hard to generalize about concepts in a tag dispatch ing API 
because concept tags need to be explicit in the dec laration of 
dispatch functions.  For all combinations of tags t hat could satisfy 
a generic function, a definition of a dispatch func tion that accepts 
those tags must be provided.  For center()  this is merely one for 
each concept, but for a function such as distance()  it is all pairs 
and becomes cumbersome once the number of concepts in the namespace dispatch { 
  template <typename TAG1, typename TAG2,  
            typename G1, typename G2> 
  struct distance {}; 
  template <typename P1, typename P2> 
  struct distance<point_tag, point_tag, P1, P2> { 
    static typename distance_result<P1, P2>::type  
    calculate(const P1& p1, const P2& p2) {…}; 
  }; 
  template <typename P, typename L> 
  struct distance<point_tag,linestring_tag,P,L> { 
    template<typename S> 
    static typename distance_result<P1, P2>::type 
    calculate(const P& point, const L& linestr); 
} 
template <typename G1, typename G2> 
typename distance_result<G1, G2>::type 
distance(const G1& g1, const G2& g2) { 
  return  
  dispatch::distance< tag<G1>::type,  
    tag<G2>::type, G1, G2>::calculate(g1, g2); 
} 
 system exceeds just a handful.  The number of such dispatch 
functions needed to implement an API explodes if so me other 
abstraction is not used, such as multi-stage dispat ch.  Another way 
to achieve that additional abstraction is inheritan ce sub-typing of 
tags, while SFINAE provides a third. 
3.  GTL’s Approach to Generic Geometry 
Empty concept struct s are defined for the purposes of meta-
programming in terms of concepts and are analogous to tags used 
in tag dispatching.  Sub-typing relationships betwe en concepts 
(concept refinements) are implemented by specializi ng meta-
functions that query for such.   
 
Even with concepts inherited from each other (for t ag 
dispatching purposes, for instance) such meta-funct ions would 
still be convenient for SFINAE checks because inher itance 
relationships are not easily detected at compile ti me.  The use of 
boost::is_base_of could obviate the need for these meta-
functions in GTL.   
Traits related to geometry concepts are broken down  into 
mutable and read-only traits structs.  A data type that models a 
concept must provide a specialization for that conc ept’s read-only 
traits or conform to the default traits definition.   It should also do 
the same for the mutable traits if possible.   
GTL interfaces follow a geometric programming style  called 
isotropy, where abstract ideas like orientation and  direction are 
program data.  Direction is a parameter to function  calls rather 
than explicitly coded in function names and handled  with flow 
control.  The access functions in the traits of a p oint data type 
therefore defines one get()  function that accepts a parameter for 
horizontal or vertical axis component rather than s eparate x()  and 
y()  access functions.    
A data type that models a refinement of a concept w ill 
automatically have read only traits instantiate for  the more general 
concept based upon the traits of the refinement tha t data type 
models.  The programmer need only provide concept m apping 
traits for the exact concept their object models an d it becomes 
fully integrated into the generic type system.   Concept checking is performed by looking up the con cept 
associated with a given object type by meta-functio n 
geometry_concept<T>  and using that along with pertinent 
concept refinement relationships through compile ti me logic to 
produce a yes or no answer for whether a given func tion should 
instantiate for the arguments provided or result in  SFINAE 
behavior in the compiler.  This allows generic func tions to be 
overloaded in GTL.  The two generic functions foo()  in the 
example code below differ only by return type, but are not 
ambiguous because their return types cannot both be  instantiated 
for the same template argument type.  While SFINAE generic 
function overloading is quite powerful and flexible , the compiler 
support for it is currently inconsistent, requiring  significant effort 
and knowledge of compiler idiosyncrasies and their implications 
in order to produce portable code.  
 
3.1  Geometry Concepts Provided by GTL 
GTL provides geometry concepts that are required to  support 
planar polygon manipulation.  A summary of these co ncepts can 
be found in Table 1. 
Table 1. GTL Concepts 
Concept Abbreviation 
coordinate_concept C 
interval_concept I 
point_concept PT 
point_3d_concept PT3D 
rectangle_concept R 
polygon_90_concept P90 
polygon_90_with_holes_concept PWH90 
polygon_45_concept P45 
polygon_45_with_holes_concept PWH45 
polygon_concept P 
polygon_with_holes_concept PWH 
polygon_90_set_concept PS90 
polygon_45_set_concept PS45 
polygon_set_concept PS 
 
Concept refinement relationships in GTL are shown i n 
Figure 2, with concepts labeled by the abbreviation s listed in 
Table 1.  GTL provides algorithms that have been op timized for 
Manhattan and 45-degree VLSI layout data, and conce pts specific 
to these restricted geometries are named with 90 an d 45.   template <typename T> struct is_integer {}; 
template <>  
struct is_integer<int> { typedef int type; }; 
template <typename T> struct is_float {}; 
template <>  
struct is_float<float> { typedef float type; }; 
 
template <typename T> 
typename is_int<T>::type foo(T input); 
template <typename T> 
typename is_float<T>::type foo(T input); 
Figure 2. GTL Concept Refinement Diagram template <typename T> 
struct point_traits { 
  typedef T::coordinate_type coordinate_type; 
  coordinate_type get(const T& p,  
    orientation_2d orient) { return p.get(orient); 
} 
template <typename T> 
struct point_mutable_traits { 
  void set(const T& p, orientation_2d orient, 
           coordinate_type value) { 
    p.set(orient, value); 
  }  
  T construct(coordinate_type x,  
    coordinate_type y) { return T(x, y); } 
}; 
 struct polygon_concept {}; 
struct rectangle_concept {}; 
template <typename T> 
struct is_a_polygon_concept{}; 
template <> struct is_a_polygon_concept< 
  rectangle_concept> { typedef gtl_yes type; }; A polygon set in our terminology is any object that  is 
suitable for an argument to a polygon set operation  (intersection, 
union, disjoint union, etc.)  A vector of polygons is a natural and 
convenient way to define such an object.  Vectors a nd lists of 
objects that model polygon and rectangle concepts a re 
automatically models of polygon sets concepts.  A u ser can define 
the traits for their polygon data type, register it  as a 
polygon_concept  type by specializing geometry_concept<T>  
and immediately begin using vectors of those polygo ns as 
arguments to GTL APIs that expect objects that mode l 
polygon_set_concept .  GTL also provides data structures for 
polygon set objects that store the internal represe ntation suitable 
for consumption by the Booleans algorithms. 
3.2  Generic Functions Provided 
It is very important to make use of the concept ref inement 
definition of parent concept traits with child conc ept objects to 
allow a complete and symmetric library of generic f unctions to be 
implemented in a manageable amount of code.  O(n) g eneric 
functions defined for O(m) conceptual types can all ow O(n * m) 
function instantiations that all operate on distinc t conceptual 
types.  A good example of this is the assign()  function that 
copies the second argument to the first and is prov ided in lieu of a 
generic free assignment operator, which is not lega l C++ syntax.  
The assign()  function can be called on any pair of objects 
where the second is the same conceptual type as the  first or a 
refinement of the first conceptual type.  GTL allow s roughly fifty, 
functionally correct and semantically sensible, ins tantiations of 
assign()  that accept distinct pairs of conceptual types.  T here is, 
however, only one SFINAE overload of the generic as sign 
function for each of thirteen conceptual types.  No  nonsensical 
combination of concepts passed to assign()  is allowed to 
compile and the syntax error generated is simply “n o function 
assign that accepts the arguments...” 
The assign()  function alone turns GTL into a Rosetta-
stone of geometry data type conversions, but the li brary also 
provides a great many other useful functions such a s area, 
perimeter, contains, distance, extents etc.  Becaus e of the 
extensible design, it is very feasible to add new f unctions and 
concepts over time that work well with the existing  functions and 
concepts.  
3.3  Bending the Rules with view_as 
Sometimes use of GTL APIs with given types would be  illegal 
because the of a conceptual type mismatch, yet the programmer 
knows that some invariant is true at runtime that t he compiler 
cannot know at compile time.  For example, that a p olygon is a 
rectangle, or degenerate.  In such cases, the progr ammer might 
want to view an object of a given conceptual type a s if it were a 
refinement of that conceptual type.  In such cases the programmer 
can concept-cast the object to the refined concept type with a 
view_as  function call.  A call to view_as  provides read only 
access to the object through the traits associated with the object.  
For example, some algorithms may be cheaper to appl y on 
concepts that place restrictions on the geometry da ta through 
refinement because they can safely assume certain i nvariants.  It is 
much faster to compute whether a rectangle fully co ntains a 
polygon than it is to compute whether a polygon ful ly contains a 
polygon.  Rather than construct a rectangle from th e polygon we can simply view the polygon as a rectangle if we kn ow that to be 
the case at runtime. 
 
The ability to perform concept casting, concept ref inement 
and overload generic functions by concept type resu lts in a 
complete C++ concepts-based type system. 
4.  Booleans Operator Templates 
The Booleans algorithms are the core algorithmic ca pability 
provided by GTL.  An example of a Boolean XOR opera tion on 
two polygons is shown in Figure 1.  The geometry co ncepts and 
concept based object model are focused on providing  mechanisms 
for getting data in and out of the core Booleans in  the format of 
the user’s choosing.  This enables the user to dire ctly make use of 
the API provided by GTL for invoking these algorith ms on their 
own data types.  This novel ability to make use of library APIs 
with application data types motivates us to provide  the most 
productive, intuitive, concise and readable API pos sible.  We 
overload the C++ bit-wise Boolean arithmetic operat ors to 
perform geometric Boolean operations because it is immediately 
intuitive, maximally concise, highly readable and p roductive for 
the user to apply. 
4.1  Supported Operators 
A Boolean operator function call is allowed by the library for any 
two objects that model a geometry concept for which  an area 
function call makes sense.  These include the operator&  for 
intersection, operator|  for union, operator^  for disjoint-union 
and operator–  for the and-not/subtract Boolean operation.  Self-
assignment versions of these operators are provided  for left hand 
side objects that model the mutable polygon set con cepts, which 
are suitable to store the result of a Boolean. Also  supported for 
such objects are operator+ /operator-  when the right hand side 
is a numeric for inflate/deflate, known as offsetti ng or buffering 
operations.  There is no complement operation becau se the ability 
to represent geometries of infinite extent is not e xpected of 
application geometry types.  Nor is such an operati on truly needed 
when object ^ rectangle  with a suitably large rectangle is 
equivalent for practical purposes.  
4.2  Operator Templates Definition 
To avoid the unnecessary copying of potentially lar ge data 
structures as the return value of an operator funct ion call that must 
return its result by value, the return value of GTL  Boolean 
operators is an operator template.  The operator te mplate caches 
references to the operator arguments and allocates storage for the 
result of the operation, which remains empty initia lly, allowing 
the copy of the operator template to be lightweight  when it is 
returned by value.  The operator template lazily pe rforms the 
Boolean operation, storing the output only when fir st requested.  if(is_rectilinear(polygon) &&  
   size(polygon) == 4) { 
  //polygon must be a rectangle 
  //use cheaper O(n) algorithm 
  return contains(view_as< 
    rectangle_concept>(polygon), polygon2); 
} else { 
  //use O(n log n) Booleans-based algorithm 
  return contains(polygon, polygon2); 
} 
 Operator templates are expected to be temporaries w hen operators 
are chained.  For instance (a + b) - c  produces an operator 
template as the result of a + b , passes that into operator-  and 
another operator template is returned by operator- .  Only later 
when the result of that operator-  is requested will both the 
Booleans be performed as the operator templates rec ursively 
perform lazy evaluation of the expression.  Because  the user is not 
expected to refer to the operator templates by type , but instead use 
them only as temporaries, there is little danger of  the arguments 
going out of scope before the expression is evaluat ed.    
4.3  Exemplary User Code 
The combination of operator templates with the C++ concepts 
based type system leads to the ability to write exe mplary user code 
using the library.  For instance, in an application  that defines its 
own CBoundingBox  and CPolyon,  the following GTL based 
code snippet becomes possible: 
 
The application of five GTL library algorithms is a ccomplished in 
only two lines of code while the design intent of t he code is clear 
and easy to read.  This is with application rather than library data 
types and no performance is sacrificed for data cop y to satisfy the 
syntactic requirements of library interfaces or the  operator 
semantics of C++ that require return by value.  Thi s abstracts 
away the low-level details of the algorithms and al lows the user to 
program at a higher level of abstraction while at t he same time 
preserving the optimality of the code produced. 
5.  Generic Sweep-line for Booleans 
A common way to implement Booleans is to first inte rsect 
polygon edges with an algorithm such as Bentley Ott mann [1].  
After line segment intersection, new vertices are c ommonly 
introduced on edges where intersections were identi fied along 
with crosslinks that stitch the input polygons toge ther into a graph 
data structure.  The graph data structure is then t raversed and a 
rules-based algorithm ensures that interior edges a re not traversed.  
Traversing exterior edges yields closed polygons. [ 12] This 
traditional algorithm has several problems.  The gr aph data 
structure is expensive to construct, expensive to s tore and 
expensive to traverse.  When the graph is traversed  to output 
polygons the winding direction can be used to ident ify holes, but 
no information stored within the graph helps to ass ociate those 
holes to the outer polygons, requiring that additio nal computation 
be performed if that information is needed.  The al gorithm leads 
to complex implementations of rule logic because it  requires that 
degeneracy be handled explicitly with logic, making  it challenging 
to achieve a reliable implementation of the algorit hm.    
A much better approach to Booleans is the applicati on of 
sweep-line to identify interior edges.  GTL provide s a generic 
sweep-line algorithm framework that is used to impl ement line 
segment intersection, Booleans and related algorith ms such as 
physical connectivity extraction.   5.1  Better Booleans through Calculus 
Our Booleans algorithm differs from the traditional  approaches 
found in the literature.  The algorithm most closel y resembles [11] 
in that it can perform polygon clipping and line se gment 
intersection with a single pass of sweep-line.  In our problem 
formulation we model a polygon as a mathematical fu nction of 
two variables x and y such that for all x/y points inside the 
polygon the function returns one, and for all point s outside the 
polygon the function returns zero.  This view of a polygon is 
useful because it allows us to reason about the pro blem 
mathematically. 
If we consider a mathematical function of two varia bles, we 
can apply the partial derivative with respect to ea ch of those 
variables, which provides the points at which the f unction value 
changes and the directions and magnitudes in which it is 
changing.  Because our geometry is piece-wise linea r this reduces 
the two dimensional definition of the polygon funct ion to a 
collection of zero dimensional quantities at its ve rtices that are 
directed impulses with magnitude of positive or neg ative one.    
 
Integrating with respect to x and y allows us to re construct 
the two dimensional polygon function from these zer o 
dimensional derivative quantities.  
 
This integration with respect to x and y in mathema tical 
terms is analogous to programmatically sweeping fro m left to 
right and from bottom to top along the sweep-line a nd 
accumulating partial sums.  Because the polygons ar e piecewise 
linear this summation is discreet rather than conti nuous and is 
therefore computationally simple.  What this mathem atical model 
for calculus of polygons allows us to do is superim pose multiple 
overlapping polygons by decomposing them into verte x objects 
that carry data about direction and magnitude of ch ange along the 
edges that project out of those vertices.  Because these vertices are 
zero-dimensional quantities they can be superimpose d simply by 
placing them together in a collection, trivially so rting them in the 
order they are to be scanned and summing any that h ave the same 
point in common.  When scanned, their magnitudes ar e summed 
(integrated) onto intervals of the sweep-line data structure.  The 
sweep-line data structure should ideally be a binar y tree that Figure 4. Integrating polygon-derivative reproduces  polygon Figure 3. Derivative of a polygon void foo(list<CPolygon>& result,  
const list<CPolygon>& a,  
const list<CPolygon>& b) { 
CBoundingBox domainExtent; 
gtl::extents(domainExtent, a); 
result += (b & domainExtent) ^ (a - 10); 
} 
 provides amortized log(n) lookup, insertion and rem oval of these 
sums, keyed by the lower bound of the interval (whi ch of course 
changes as the sweep-line moves.)  Each such interv al on the 
sweep-line data structure stores the count of the n umber of 
polygons the sweep-line is currently intersecting a long that 
interval.  Notably, the definition allows for count s to be negative.  
A union operation is performed by retaining all edg es for which 
the count above is greater than zero and the count below is less 
than or equal to zero or visa-versa.  Vertical edge s are a special 
case because they are parallel to our sweep-line bu t are easily 
handled by summing them from bottom to top as we pr ogress 
along the sweep-line. 
 
The sequence of steps to perform a Boolean OR (unio n) 
operation on two polygons is shown in Figure 5.  Th e two input 
polygons are shown overlapping in Figure 5 a.  They  are 
decomposed into their derivative points as shown in  Figure 5 b.  
Line segment intersection points are inserted as sh own in Figure 5 
c.  These intersection points carry no derivative d ata quantities 
because no change in direction of edges takes place  at intersection 
points.  The result of a pass of sweep-line to remo ve interior 
points through integration and output updated deriv ative 
quantities is shown in Figure 5 d.  Note that it is  the same data-
format as the input shown in Figure 5 b and is in f act the 
derivative of the output polygons.  This facilitate s the chaining 
together of multiple Booleans operations without th e need to 
convert to and from polygons in between.  Note that  one point in 
Figure 5 d. has no derivative vector quantities ass igned to it.  That 
point is collinear with the previous and next point  in the output 
polygon and therefore doesn’t represent a change in  direction of 
edges.  It is retained because preserving the topol ogy of collinear 
points in the output is a requirement for some mesh ing algorithms 
that their input polygons be “linearly consistent.”   Such collinear 
points can be trivially discarded if undesired.  A final pass of 
sweep-line can either integrate the output polygon derivative from 
Figure 5 d to form polygons with holes as shown in Figure 5 e or 
keyhole out the holes to the outer shells as shown in Figure 5 f.  It 
is possible to perform line segment intersection, i nterior point 
removal and form output polygons in a single pass o f sweep-line.  
We break it down into separate steps for convenienc e.  The 
computation required for interior point removal, up dating of 
derivative quantities and formation of output polyg ons increases the computational complexity of sweep-line based ge neralized 
line segment intersection such as that described by  [1] by only a 
constant factor whether performed as a single pass or separated 
into multiple passes.  The algorithm presented here  is therefore 
optimal because it is well known that polygon clipp ing is bounded 
by the complexity of line segment intersection, as can be trivially 
proven because line segment intersection could be i mplemented 
with our polygon-clipping algorithm.   
The output polygons can contain holes, and the inpu t 
polygons can likewise contain holes.  Moreover, the  output holes 
can be associated to their outer shells as addition al data available 
in the output or geometrically by keyholing.  The o utput can 
easily be obtained as the non-overlapping trapezoid  
decomposition of polygons sliced along the sweep-li ne orientation 
similar to [11].  All of these polygonal forms of o utput are legal 
inputs to the algorithm, and it is closed both on t he polygon 
domain as well as the polygon derivative domain mea ning that it 
consumes its own output.  The other advantage of th is algorithm 
over the traditional previous polygon clipping algo rithms is that it 
correctly handles all degeneracy in inputs implicit ly with the same 
logic path that handles the normal case.  Our algor ithm reduces 
the complex logic of categorizing states to simple arithmetic 
applied while scanning.  It is robust to negative p olygon counts 
(holes outside of shells), high order overlaps of i ntersections and 
edges, co-linear and duplicate points, zero length edges, zero 
degree angles and self-intersecting/self-overlappin g polygons, all 
by simply applying the same calculus of summing der ivative 
values that are easily computed by inspecting each polygon 
vertex.  To our knowledge this polygon-derivative d ata-modeling 
and algorithm for polygon clipping has not appeared  in past 
literature and is novel. 
5.2  Generic Booleans Algorithmic Framework 
The scanning of geometry for a Boolean in GTL perfo rms 
integration with respect to x and y of changes in c ounts of the 
number of polygons from left-to-right/bottom-to-top .  The sweep-
line data structure stores the current count of the  number of 
polygons that overlap intervals of the sweep-line.  We employ the 
stl map for our sweep-line data structure using a s imilar technique 
as described in [9] to implement a comparison funct or that 
depends upon the position of the sweep-line.  The c ount data type 
stored as the value of the map element is a templat e parameter of 
the sweep-line algorithm.  It is required to be add able, and 
generally conform to the integral behaviors.  An in teger is a valid 
data type for the count and is used to implement un ary Boolean 
operations.  A pair of integers can be used to impl ement binary 
Boolean operations such as intersection.  A map of property value 
to count can be used to perform sweep-line on an ar bitrary 
number of input geometry “layers” in a single pass.   Other 
template parameters include an output functor, outp ut data 
structure and of course the coordinate data type.   
 Figure 5. Sequence of Boolean OR (union) operation 
template <typename coordinate_type> 
struct boolean_op { 
  template <typename count, typename output_f> 
  struct sweep_line { 
    template <output_c, input_i> 
    void scan(output_c& o, input_i b, input_i e); 
  }; 
}; The generic algorithm takes care of all the details  of 
intersecting polygon edges and summing counts while  the output 
functor, count data type and output data structure control what is 
done with that information.  In this way, the algor ithm can be 
adapted to perform multiple operations with minimal  effort.  The 
seven simple Booleans supported by GTL employ outpu t functors 
that differ only in the logic they apply to the cou nt data type. 
 
If the logic applied by these output functors to th e count 
results in true on one side of an edge and false on  the other then 
that edge is exterior and appended to the output da ta structure.  If 
partial polygons are stored as part of the count da ta structure in 
the sweep-line tree then the output functor can con struct output 
polygons. 
 
Also implemented with the generic Booleans framewor k are 
property merge and connectivity extraction.  By usi ng a map of 
property to polygon count as the data type for the counts stored on 
the sweep-line and appropriate output functor and o utput data 
structure the connectivity graph of n nodes of poly gonal inputs 
can be computed in a single pass of the algorithm t o provide a 
solution to the spatial overlay join problem.  An e xample of the 
output of this algorithm for the geometry in Figure  6 a. is shown 
in Figure 6 b.  Similarly, the geometry of all uniq ue combinations 
of overlap between n polygonal inputs can be comput ed and 
output by the property merge output functor to a ma p of polygon 
sets keyed by sets of property values.  An example of the output of 
property merge for the geometry in Figure 6 a. is s hown in Figure 
6 c.  The property merge algorithm is a generalizat ion of two 
input Boolean operations to n inputs to solve the n -layer map 
overlay problem.  The generic algorithm can be easi ly adapted to 
implement other sweep-line based algorithms includi ng domain 
specific algorithm such as capacitance estimation. 
5.3  Offsetting/Buffering Operations 
In addition to Booleans, GTL also provides the capa bility to offset 
polygons by “inflating” or “deflating” them by a gi ven resizing 
value.  Polygons grow to encompass all points withi n the resizing 
distance of their original geometry.  If the resizi ng distance is negative, polygons shrink.  This implies that circu lar arcs be 
inserted at protruding corners when a polygon is re sized.  Such 
circular arcs are segmented to make the output poly gonal.  Other 
options for handling such corners include inserting  a single edge 
instead of an arc, simply maintaining the original topology or 
leaving the corner region unfilled.  The resizing o perations are 
accomplished by a union operation on the original p olygons with 
a collection of trapezoids constructed from their e dges of width 
equal to the resizing distance and with polygons at  the corners 
generated based on the two adjacent edge trapezoids .  An example 
of the shapes created from the input 45-degree geom etry in Figure 
7 a is shown in Figure 7 b and the result of the un ion between 
those shapes and the original to create the output geometry of an 
inflate operation is shown in Figure 7 c.  Deflate is accomplished 
by substituting subtraction for union. 
 
6.  Numerical Robustness 
There are three problems in integer arithmetic that  must be 
overcome to implement generalized line segment inte rsection for 
polygon clipping.  These are integer overflow, inte ger truncation 
of fractional results and integer snapping of inter section points.  
Overflow and truncation of fractional results makes  computing the 
result of very innocent looking algebraic expressio ns all but 
impossible with built-in integer types.  The common  practice of 
resorting to floating point arithmetic in these cas es is clearly not 
suitable because the error it introduces is even mo re problematic.  
Intersection points must be snapped to the integer grid at the 
output of the algorithm.  However, snapping the int ersection point 
causes a small lateral movement of the line segment s it is inserted 
on.  This movement can cause a line segment to cros s to the other 
side of a vertex than was at the case in the input,  introducing new 
intersections.  If these new intersections have not  yet been reached 
by the forward progress of the line segment interse ction sweep-
line, they might be handled naturally by the algori thm, however, it 
is just as likely they are introduced prior to the current position of 
the sweep-line and the algorithm will not have the opportunity to 
handle them during its forward progress. 
A choice about how to handle spurious intersection points 
introduced by intersection point snapping must be m ade.  It is 
impossible to both output the idealized “correct” t opology of 
intersected line segments and at the same time outp ut fully 
intersected line segments with their end points on the integer grid 
with the property that no two line segments interse ct except at 
their end points.  The invariant that output line s egments not 
intersect except at their end points is crucial bec ause this invariant 
is a requirement of algorithms that would consume t he output.  
Topologically, the important consideration for poly gon clipping is 
that the output edges describe closed figures.  Vio lating this 
invariant would, at best, cause polygons to be “dro pped” during 
subsequent execution and, at worst, result in undef ined behavior.  Figure 6. Connectivity Extraction and Property Merg e Figure 7. Resize Example: inflate of polygon with h ole //intersect 
count[0] > 0 && count[1] > 0; 
//union 
count[0] > 0 || count[1] > 0; 
//self-union 
count > 0 
//disjoint-union 
(count[0] > 0) ^ (count[1] > 0) 
//subtract 
(count[0] > 0) && !(count[1] > 0) 
//self-intersect 
(count > 1) 
//self-xor 
(count % 2) 
 It is obvious that merging of vertices and the inse rtion of new 
vertices are both topological changes that preserve  the property of 
the network that all closed cycles remain closed.  These 
topological changes are allowed to occur as the res ult of snapping 
intersection points because we choose to enforce th e invariant that 
no line segments at the output intersect except at their end points. 
6.1  Solving Overflow and Truncation  
Overflow is easy to handle if the appropriate data types are 
available.  Thirty-two bit can be promoted to sixty -four and sixty-
four bit can be promoted to multi-precision integer .  However, in 
generic code it becomes impossible to be explicit a bout when to 
cast and what to cast to.  The same algorithm might  be applied on 
several different coordinate data types when instan tiated with 
different template parameters.  We provide indirect  access to the 
appropriate data types through coordinate traits, a  coordinate 
concept and a meta-function: high_precision_type<T> .  The 
coordinate traits allow the lookup of what data typ e to use for 
area, difference, Euclidean distance, etc.  The coo rdinate concept 
is used to provide algorithms that apply these data  types correctly 
to ease the burden of common operations such as com puting the 
absolute distance between two coordinate values in one-
dimensional space.  The high precision type is used  where built-in 
data types would not be sufficient.  It defaults to  long double, 
which is the highest precision built-in data type, but still 
potentially insufficient.  By specializing for a sp ecific coordinate 
data type such as integer, a multi-precision ration al such as the 
gmp mpq type [3] can be specified.  This can be don e outside the 
GTL library itself, making it easy to integrate lic ense encumbered 
numerical data types with GTL and its boost license  without the 
need for the GTL code itself to depend on license e ncumbered 
header files. 
Handling integer truncation of fractional results c an be done 
either by applying the high-precision type (prefera bly a multi-
precision rational) or by algebraic manipulation to  minimize the 
need for division and other operations that may pro duce factional 
results.  Some examples of this are distance compar ison, slope 
comparison and intersection point computations.  Wh en 
comparing the distances between two points it is no t necessary to 
apply the square root operation because that functi on is 
monotonic.  When comparing slopes we use the cross- product as a 
substitute for the naïve implementation.  This avoi ds division and 
produces reliable results when performed with integ er data types 
of sufficient precision.  Comparing intersection co ordinates can 
also use the cross product to avoid division becaus e computing 
the intersection point of two line segments can be algebraically 
manipulated to require only a single division opera tion per 
coordinate, which is performed last. 
 6.2  Solving Spurious Intersections 
Non-integer intersection points need to be snapped to the integer 
grid in the output.  We snap each intersection poin t to the integer 
grid at the time it is identified.  We do this by t aking the floor of 
the fractional value.  Integer truncation is platfo rm dependent, but 
frequently snaps toward zero, which is undesirable because it is 
not uniformly consistent.  Because the integer grid  is uniform, the 
distance a point can be snapped by taking the floor  is bounded to 
a 1x1 unit integer grid region.   Our current appro ach differs from 
the similar approach described by John Hobby [4] in  that he 
rounds to the nearest integer. 
Because the distance a segment can move is bounded,  it is 
predictable.  That means that we can predict the di stance a 
segment might move due to a future intersection eve nt and handle 
any problems that would cause pro-actively in the e xecution of 
line segment intersection.  There are two types of intersection 
artifacts created by snapping.  The first is caused  when a line 
segment moves laterally and crosses a vertex, causi ng intersection 
with edges that would not otherwise be intersected.   The second is 
when an output line sub-segment is lengthened by sn apping and 
its end point crosses a stationary line segment.  T he second case is 
functionally equivalent to the first since it doesn ’t matter whether 
a point moves to cross an edge or an edge moves to cross a point.  
Both can be handled by the same strategy so we’ll f ocus on the 
case of the line segment moving in the description of our strategy.  
That strategy relies upon the following lemma: all artifacts take 
place only when a vertex lies within a distance of a line segment 
bounded by the max distance an intersection point c an be 
snapped.  This lemma can be trivially proven becaus e the distance 
that segments can move is bounded and it is obvious ly impossible 
for two non-intersecting line segments to cross eac h other without 
one first crossing an end-point of the other.  More over, since the 
direction of snapping is known to be always downwar d, it follows 
that a vertex can only be crossed by a line segment  if that line 
segment intersects the 1x1 integer unit grid box wi th that vertex in 
its lower left corner.  In these cases, we intersec t the line segment 
with those vertices pro-actively such that if a fut ure intersection 
causes the line segment to move, the output topolog y cannot 
contain spurious intersection artifacts due to that  event.  Because 
the vertex is intersected and not other edges, no a dditional line 
segment intersections need be introduced and no pro pagation of 
intersection artifacts through the network can take  place.  This 
method in known as snap-rounding and has been much discussed 
in the literature. [4]  
Given an algorithm that finds intersections between  line 
segments, it is easy to find intersections with 1x1  integer grid 
boxes at segment end-points and snapped-intersectio n points by 
modeling them as several tiny line segments called a widget.  Any 
line segment that intersects the unit grid box will  intersect at least 
one of the segments of the widget shown in Figure 8 . 
 
Importantly, intersection events are detected by th e algorithm 
based on only the input line segments geometry and never that of Figure 8. Example: Vertex/Segment Intersection Widg et //Segment 1: (x11,y11) to (x12, y12) 
//Segment 2: (x21,y21) to (x22, y22) 
x = (x11 * dy1 * dx2 – x21 * dy2 * dx1 +  
     y21 * dx1 * dx2 - y11 * dx1 * dx2) /  
     (dy1 * dx2 - dy2 * dx1);  
y = (y11 * dx1 * dy2 - y21 * dx2 * dy1 +  
     x21 * dy1 * dy2 - x11 * dy1 * dy2) /  
     (dx1 * dy2 - dx2 * dy1);  
 the intersected line segments it has produced.  Oth erwise, 
numerical error could propagate forward in cascadin g increased 
severity to reach arbitrarily large magnitudes.  If  such were the 
case, no assurance of numerical robustness could be  reasonably 
made.   
If the snapping direction is uniform it can be arra nged so that 
vertices snap forward in the scanning direction all owing 
evaluation of the widget to be performed by the sam e sweep-line 
that finds the intersections.  This is our intentio n.  However, 
currently our arbitrary angle polygon Booleans appl y a much 
simpler line segment intersection algorithm impleme nted to 
validate the sweep-line version of robust line segm ent 
intersection, which is still a work in progress.  I t compares all 
pairs of line segments that overlap in their x coor dinate range and 
all vertices and snapped intersection points with a ll segments that 
overlap with the x coordinate of those points.  It has O(n^2) worst 
case runtime complexity, but in the common case it has expected 
runtime of O(n 3/2 ) and, in practice, performs nearly as well as the 
expected O(n log n) runtime of the optimal algorith m, making its 
use for even quite large input data sets highly pra ctical. 
The combination of handling overflow and applying r ational 
data types to overcome truncation errors with the s trategy for 
mitigating errors introduced by intersection point snapping allows 
100% robust integer line segment intersection.  The  algorithm 
approximates output intersection points to within o ne integer unit 
in x and y and may intersect line segments with poi nts that lie 
within one integer unit in x and y.  This approxima tes the ideal 
“correct” output to the extent practical with integ er coordinates.  
The algorithm could be enhanced to round to closest  integer grid 
point when snapping intersections and make intersec ting segments 
to nearby vertices predicated upon whether it later  becomes 
necessary to do so.  As a practical matter, however , these 
measures would result in very little benefit to acc uracy.  That 
benefit, and more, can be more easily obtained by s caling up the 
input and applying higher precision integer arithme tic, if 
necessary, which is easily accomplished using GTL. 
7.  Experimental Results 
We benchmarked our own GTL polygon clipping Boolean s 
algorithm against the GPC [7], PolyBoolean [6] and CGAL [8] 
polygon clippers.  We benchmarked the three GTL alg orithms, 
Manhattan, 45-degree, and general Booleans against all three.  
These benchmarks were performed on a two-package, 8  core, 3.0 
GHz Xenon with 32 GB of RAM, 32 KB of L1 cache and 6 MB 
L2 cache.  Hyper-threading was disabled.  None of t he algorithms 
tested were threaded and all ran in the same proces s.  We 
compiled the benchmark executable using gcc 4.2.2 w ith O3 and 
finline-limit=400 optimization flags. 
Inputs consisted of small arbitrary triangles, arbi trarily 
distributed over square domains of progressively in creasing size.  
Runtimes measured were the wall-clock execution tim e of the 
intersection operation on geometry contained within  two such 
domains.  The overlapping triangles in each domain had to be 
merged first with GTL to make them legal inputs for  the other 
three libraries’ Boolean operations.  For the Manha ttan (axis-
aligned rectilinear) benchmark we used small arbitr ary rectangles 
instead of triangles.  Results of our benchmarking are shown in Figures 9,  10 and 
11.  Note that in Figure 11 the last two data point s for 
PolyBoolean are absent.  PolyBoolean suffered from unexplained 
crashes as well as erroneously returning an error c ode due to a 
bug in its computation of whether a hole is contain ed within a 
polygon.  This prevented PolyBoolean from successfu lly 
processing large data sets.  CGAL had a similar pro blem that 
prevented it from processing data sets larger than those in Figure 
11.  We conclude that this is a bug in CGAL because  both GTL 
and GPC were always successful in processing the sa me polygons.  
This issue with GCAL was observed regardless of whi ch kernel 
was employed.    
 
 
 Figure 9. GPC/GTL Scalability Comparison 
Figure 10. Rectilinear Scalability Comparison 
Figure  11. Small Scale Performance Comparison  All libraries performed roughly within the range of  2X faster 
to 2X slower than GTL for the small inputs shown in  Figure 11.  
We feel that such small constant factor variation i s not significant 
since it could likely be remedied by profile-guided  performance 
tuning of implementation details.  We did not apply  empirical 
complexity measurement on the data sets in the Gene ral 
Performance plot because non-linearity in micro-arc hitecture 
performance as memory footprints start to exceed L1  cache size 
renders such analysis on very small input sizes fau lty. 
While successful at processing all inputs, the GPC library’s 
runtime scaled sub-optimally for large inputs, as c an be seen in 
Figure 10.  The empirical runtime complexity of GPC  from that 
plot is n 2.6 , which can be clearly seen in its steep slope rela tive to 
GTL.  We were unable to measure CGAL or PolyBoolean  for this 
benchmark because of the bugs that effectively prev ented them 
from processing inputs larger than those shown in F igure 11.  
Also in Figure 9 we show the portion of GTL runtime  spent in the 
core Boolean sweep as gtlb.  Note that the runtime of GTL is 
dominated by the currently suboptimal line segment intersection, 
which we plan on eventually rectifying by integrati ng line 
segment intersection into the core Boolean sweep at  a constant 
factor overhead.   
All libraries were successful in processing large-s cale 
Manhattan polygon inputs.  There is a 100X variabil ity in 
runtimes, however, as can be seen in Figure 10.  Th e Manhattan 
Booleans algorithm in GTL is labeled gtl90 in the f igure, and the 
45-degree Booleans algorithm is labeled gtl45.  Not e that the 45-
degree algorithm is optimal, computing line segment  intersection 
in the same sweep as the Boolean operation, and per forms within 
a small constant factor of the similar 90-degree al gorithm.  Again, 
we show the portion of the general Booleans algorit hm labeled 
gtlb.  We believe that when upgraded with optimal l ine segment 
intersection the general Booleans algorithm could p erform closer 
to the gtlb curve than the current performance, whi ch is labeled 
gtl.  GPC and PolyBoolean both turn in suboptimal n1.8  runtime 
scaling in this benchmark.  CGAL appears to be opti mal for this 
benchmark, scaling at a near linear n 1.07 .  Frequently we have 
observed O(n log n) algorithms will have an empiric al scaling 
factor of less than one for input ranges that are m odest in size, as 
we see in both log-log plots for gtlb as well as fo r gtl90.  This is 
because the micro-architecture has advanced feature s such as 
speculative memory pre-fetch that become more effec tive as input 
vector sizes grow.  However, it clearly demonstrate s that empirical 
scaling observations must be interpreted cautiously  when drawing 
conclusions about algorithmic complexity and optima lity.  Our 
review of GPC and PolyBoolean code lead us to belie ve that their 
line segment intersection algorithms should perform  at around 
n1.5 log n on the test data we generated.  Our conclusio n that they 
are suboptimal is not based upon empirical data alo ne. 
8.  Conclusion 
Our C++ Concepts based API for planar polygon manip ulations 
makes these powerful algorithms readily accessible to applications 
developers.  Improvements in our Booleans algorithm  over prior 
work frees users of that API from the hassles of ac commodating 
library restrictions and conventions imposed upon i nput 
geometries, while the C++ Concepts based API frees them from 
syntactic restrictions on how the algorithms may be  applied.  Because our library compares favorably with similar  open-source 
libraries, in terms of both performance and feature  set, while 
providing a superior API based upon generic program ming 
techniques, we feel that it is a good candidate for  acceptance into 
boost and plan to pursue review this year. 
9.  ACKNOWLEDGMENTS 
Our thanks to Fernando Cacciola for technical guida nce and 
editorial review and to Intel for supporting our wo rk. 
10.  REFERENCES 
[1]  Bentley, J.L., Ottmann, T.A. Algorithms for reporti ng and 
counting geometric intersections. IEEE Transactions on 
Computers, 9 , (C-28), 643-647. 
[2]  Gehrels, B., Lalande, B. Generic Geometry Library, 2009. 
Retrieved February 17 2009, from boost: 
https://svn.boost.org/svn/boost/sandbox/ggl 
[3]  GMP Gnu Multi-Precision Library, 2009. Retrieved Au gust 
9, 2008, from gmplib.org: http://gmplib.org 
[4]  Hobby, J. Practical segment intersection with finit e precision 
output. Technical Report 93/2-27, Bell Laboratories  (Lucent 
Technologies), 1993.  
[5]  Kohn, B. Generative Geometry Library, 2008. Retriev ed July 
22, 2008, from boost: 
http://www.boostpro.com/vault/index.php?action=down loadf 
ile&filename=generative_geometry_algorithms.zip&dir ector 
y=Math - Geometry& 
[6]  Leonov, M. PolyBoolean, 2009. Retrieved March 15, 2 009, 
from Complex A5 Co. Ltd.: http://www.complex-
a5.ru/polyboolean/index.html 
[7]  Murta, A. GPC General Polygon Clipper library, 2009 .  
Retrieved March 15, 2009, from The University of 
Manchester: http://www.cs.man.ac.uk/~toby/alan/soft ware/ 
[8]  Pion, S. CGAL 3.3.1, 2007.  Retrieved October 10, 2 008, 
from CGAL: http://www.cgal.org 
[9]  Ruud, B. Building a Mutable Set, 2003. Retrieved Ma rch 3, 
2009, from Dr. Dobb’s Portal: 
http://www.ddj.com/cpp/184401664 
[10]  Dos Reis, G. and Stroustrup, B. 2006. Specifying C+ + 
concepts. In Conference Record of the 33rd ACM SIGPLAN-
SIGACT Symposium on Principles of Programming 
Languages  (Charleston, South Carolina, USA, January 11 - 
13, 2006). POPL '06. ACM, New York, NY, 295-308. DO I= 
http://doi.acm.org/10.1145/1111037.1111064  
[11]  Vatti, B. R. 1992. A generic solution to polygon cl ipping. 
Commun. ACM  35, 7 (Jul. 1992), 56-63. DOI= 
http://doi.acm.org/10.1145/129902.129906 
[12]  Weiler, K. 1980. Polygon comparison using a graph 
representation. In Proceedings of the 7th Annual Conference 
on Computer Graphics and interactive Techniques  (Seattle, 
Washington, United States, July 14 - 18, 1980). SIG GRAPH 
'80. ACM, New York, NY, 10-18. DOI= 
http://doi.acm.org/10.1145/800250.8074