Description: Autogenerated patch header for a single-debian-patch file.
 The delta against upstream is either kept as a single patch, or maintained
 in some VCS, and exported as a single patch instead of more manageable
 atomic patches.
Forwarded: not-needed

---
--- clippoly-0.11.orig/CLASSES
+++ clippoly-0.11/CLASSES
@@ -1,44 +1,44 @@
-ConstPolyIter:
-	A PolyIter which is constructed of a const Poly.
-
-DirPolyIter:
-	Provides an iterator for a Poly which can go forward and backwards.
-
-Edge:
-	A side of a polygon consisting of two Point's. I'm afraid this one
-	is no longer used.
-
-NodePEdge:
-	Represents an edge from a Poly.
-
-Point:
-	A 2-D point. Some arithmetic operations are overloaded.
-
-PointList:
-	List of Point's. I'm afraid that this one is no longer used.
-
-PointListIter:
-	An iterator for a PointList.
-
-Poly:
-	A polygon. Consist of a double linked list of PolyNode's.
-
-PolyIter:
-	Provides an iterator over a Poly.
-
-PolyNode:
-	A single point in a Poly.
-
-PosAdder:
-	A 'boolean' which can have the values UnKnown, True and False.
-
-Set:
-	A template implementation of a Set. Main design issue: fast to
-	implement :-)
-
-SetIter:
-	Iterator for a Set.
-
-RSet, RSetIter: 
-	Similar to the Set classes, but handle data by reference.
-
+ConstPolyIter:
+	A PolyIter which is constructed of a const Poly.
+
+DirPolyIter:
+	Provides an iterator for a Poly which can go forward and backwards.
+
+Edge:
+	A side of a polygon consisting of two Point's. I'm afraid this one
+	is no longer used.
+
+NodePEdge:
+	Represents an edge from a Poly.
+
+Point:
+	A 2-D point. Some arithmetic operations are overloaded.
+
+PointList:
+	List of Point's. I'm afraid that this one is no longer used.
+
+PointListIter:
+	An iterator for a PointList.
+
+Poly:
+	A polygon. Consist of a double linked list of PolyNode's.
+
+PolyIter:
+	Provides an iterator over a Poly.
+
+PolyNode:
+	A single point in a Poly.
+
+PosAdder:
+	A 'boolean' which can have the values UnKnown, True and False.
+
+Set:
+	A template implementation of a Set. Main design issue: fast to
+	implement :-)
+
+SetIter:
+	Iterator for a Set.
+
+RSet, RSetIter: 
+	Similar to the Set classes, but handle data by reference.
+
--- /dev/null
+++ clippoly-0.11/COPYING
@@ -0,0 +1,481 @@
+                  GNU LIBRARY GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+                  GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License").  Each licensee is
+addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    c) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    d) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
--- /dev/null
+++ clippoly-0.11/Makefile.am
@@ -0,0 +1,52 @@
+ACLOCAL_AMFLAGS = -I m4
+
+AM_CPPFLAGS = -DGEN_TEMPLATES
+
+lib_LTLIBRARIES = libclippoly.la
+
+libclippoly_la_SOURCES =
+
+# OBJ
+libclippoly_la_SOURCES += nclip.cc poly.cc poly_io.cc posadder.cc	\
+primitives.cc templates.cc version.c
+
+# LIBOBJ
+libclippoly_la_SOURCES += graphadd.cc graphmat.c graphmat++.cc
+
+check_PROGRAMS = clippolytest
+
+clippolytest_SOURCES = clippolytest.cc
+
+clippolytest_LDADD = libclippoly.la
+
+TESTS = test0 test1 test2
+
+dist_man_MANS = graphadd.3 graphmat.3 graphmat++.3
+
+dist_doc_DATA = CLASSES README
+
+cpincludedir = $(includedir)/clippoly
+
+cpinclude_HEADERS = graphadd.h graphmat.h graphmat++.h nclip.h poly.h	\
+poly_io.h posadder.h primitives.h set.h version.h
+
+EXTRA_DIST = case1 case2 case3 in_file in_file.test in_file.wrong	\
+lgpl.texinfo out_file.dist t1 t1.out t2 t2.out test0 test1 test2
+
+clippoly.pc:
+	echo 'prefix=$(prefix)'			>  $@
+	echo 'exec_prefix=$(exec_prefix)'	>> $@
+	echo 'includedir=$(includedir)'		>> $@
+	echo 'libdir=$(libdir)'			>> $@
+	echo					>> $@
+	echo 'Name: $(PACKAGE_TARNAME)'		>> $@
+	echo 'Description: $(PACKAGE_NAME)'	>> $@
+	echo 'URL: $(PACKAGE_URL)'		>> $@
+	echo 'Version: $(PACKAGE_VERSION)'	>> $@
+	echo 'Cflags: -I${includedir}'		>> $@
+	echo 'Libs: -L${libdir} -lclippoly'	>> $@
+	echo 'Libs.private: $(LDFLAGS) $(LIBS)'	>> $@
+
+pkgconfig_DATA = clippoly.pc
+
+MOSTLYCLEANFILES = $(pkgconfig_DATA)
--- clippoly-0.11.orig/README
+++ clippoly-0.11/README
@@ -1,59 +1,63 @@
-If you don't have g++, but a cfront based compiler like Sun C++ 3.0, then
-you should compile the files from the CC subdirectory to this directory.
-The String.{cc,h} files are not a complete implementation of a String class;
-they only provide what is used in the file poly_io.cc. For a good String
-class you can try the libg++ library (which I assume is installed if you
-have g++.)
-Also, rename Makefile.CC to Makefile. If you don't have g++ nor a cfront
-based compiler then you are on your own.
-Compilers which are know to work:
-g++ 2.4 -> 2.6.0 g++ 2.6.1 has a bug in constructor sysntax which break this
-code.
-Sun C++ 2.1, 3, 4
-Irix CC on Irix 5.2
-A bug which reveals itself on Ultrix mips machines is known. The fix will
-be incorporated in this code some day.
-
-Before compiling, skim through the Makefile. Three differences can be made:
-- Changing the C compiler. Standard is cc. gcc -traditional can be used on
-  systems with proper header files (this excludes SunOS 4.1.X). Ansi C
-  compilers give warnings on the C files, as they are in K&R C, and the
-  header files are ANSI C / C++.
-- Adding the notion of a .cc file as a C++ source file. Some make's (like
-  SGI's) do not standard recognize a .cc file as C++
-- Patching libg++. Early versions of libg++ 2.5 (notably, 2.5.1 and 2.5.2)
-  suffered a bug which caused the test porgram to hang. If you add
-  sbscan.cc to the program (replacing the one in libg++) this bug is fixed.
-  Better off course is to upgrade to a more recent libg++!
-  Note that libg++ 2.4.X does not have this bug, and can be used without
-  (known) problems.
-
-In this directory you can find the test program for the nclip
-library. In this directory is:
-
-lgpl.texinfo: texinfo style version of the copyright statement.
-
-test.cc: The wrapper in which we can test. Reads two clockwise
-	oriented polygons from stdin, and clips those. Results
-	comes on stdout. Examples format for input can be found in
-	in_file.
-
-nclip.cc:	The actual clip routine. Only file in the nclip
-	library which is decent documented.
-
-nclip.h nclip.cc poly.cc poly.h poly_io.cc poly_io.h posadder.cc posadder.h
-primitives.cc primitives.h set.h:
-	The rest of the nclip library. Not of real interest, but needed to
-	get nclip running.
-
-sbscan.cc:
-	Part of libg++. It is a patched version of a file from libg++ 2.5.1
-
-err.* graph*:
-	files, part of our standard , in-house library. Not likely to
-	have big errors. They even come with documentation!
-	(*.3, nroff (== UNIX man) format)
-	They should be compiled with a K&R C compiler (like gcc -traditional.)
-
-CLASSES:
-	Some documentation about the classes used.
+Compiling with Visual C++ seems to work. Be carefull to make sure that
+Visual C++ knows that a .cc file is a C++ file (or rename the files.)
+
+Old information:
+If you don't have g++, but a cfront based compiler like Sun C++ 3.0, then
+you should compile the files from the CC subdirectory to this directory.
+The String.{cc,h} files are not a complete implementation of a String class;
+they only provide what is used in the file poly_io.cc. For a good String
+class you can try the libg++ library (which I assume is installed if you
+have g++.)
+Also, rename Makefile.CC to Makefile. If you don't have g++ nor a cfront
+based compiler then you are on your own.
+Compilers which are know to work:
+g++ 2.4 -> 2.6.0 g++ 2.6.1 has a bug in constructor sysntax which break this
+code.
+Sun C++ 2.1, 3, 4
+Irix CC on Irix 5.2
+A bug which reveals itself on Ultrix mips machines is known. The fix will
+be incorporated in this code some day.
+
+Before compiling, skim through the Makefile. Three differences can be made:
+- Changing the C compiler. Standard is cc. gcc -traditional can be used on
+  systems with proper header files (this excludes SunOS 4.1.X). Ansi C
+  compilers give warnings on the C files, as they are in K&R C, and the
+  header files are ANSI C / C++.
+- Adding the notion of a .cc file as a C++ source file. Some make's (like
+  SGI's) do not standard recognize a .cc file as C++
+- Patching libg++. Early versions of libg++ 2.5 (notably, 2.5.1 and 2.5.2)
+  suffered a bug which caused the test porgram to hang. If you add
+  sbscan.cc to the program (replacing the one in libg++) this bug is fixed.
+  Better off course is to upgrade to a more recent libg++!
+  Note that libg++ 2.4.X does not have this bug, and can be used without
+  (known) problems.
+
+In this directory you can find the test program for the nclip
+library. In this directory is:
+
+lgpl.texinfo: texinfo style version of the copyright statement.
+
+test.cc: The wrapper in which we can test. Reads two clockwise
+	oriented polygons from stdin, and clips those. Results
+	comes on stdout. Examples format for input can be found in
+	in_file.
+
+nclip.cc:	The actual clip routine. Only file in the nclip
+	library which is decent documented.
+
+nclip.h nclip.cc poly.cc poly.h poly_io.cc poly_io.h posadder.cc posadder.h
+primitives.cc primitives.h set.h:
+	The rest of the nclip library. Not of real interest, but needed to
+	get nclip running.
+
+sbscan.cc:
+	Part of libg++. It is a patched version of a file from libg++ 2.5.1
+
+err.* graph*:
+	files, part of our standard , in-house library. Not likely to
+	have big errors. They even come with documentation!
+	(*.3, nroff (== UNIX man) format)
+	They should be compiled with a K&R C compiler (like gcc -traditional.)
+
+CLASSES:
+	Some documentation about the classes used.
--- clippoly-0.11.orig/case1
+++ clippoly-0.11/case1
@@ -1,14 +1,14 @@
-        223 686
-        233 230
-        673 228
-        633 436
-        357 302
-        351 448
-        487 448
-        471 692
-        PolyMagic
-        397 604
-        397 372
-        723 374
-        723 608
-        PolyMagic
+        223 686
+        233 230
+        673 228
+        633 436
+        357 302
+        351 448
+        487 448
+        471 692
+        PolyMagic
+        397 604
+        397 372
+        723 374
+        723 608
+        PolyMagic
--- clippoly-0.11.orig/case2
+++ clippoly-0.11/case2
@@ -1,12 +1,12 @@
-        137 424
-        535 270
-        483 522
-        805 678
-        165 804
-        PolyMagic
-        249 666
-        363 882
-        463 640
-        565 1028
-        187 1016
-        PolyMagic
+        137 424
+        535 270
+        483 522
+        805 678
+        165 804
+        PolyMagic
+        249 666
+        363 882
+        463 640
+        565 1028
+        187 1016
+        PolyMagic
--- clippoly-0.11.orig/case3
+++ clippoly-0.11/case3
@@ -1,10 +1,10 @@
-       799993 400015
-        800020 400003
-        800007 399985
-        799980 399997
-        PolyMagic
-        799990 399996
-        799986 400007
-        800006 400011
-        800010 400000
-        PolyMagic
+       799993 400015
+        800020 400003
+        800007 399985
+        799980 399997
+        PolyMagic
+        799990 399996
+        799986 400007
+        800006 400011
+        800010 400000
+        PolyMagic
--- /dev/null
+++ clippoly-0.11/clippolytest.cc
@@ -0,0 +1,70 @@
+//    nclip: a polygon clip library
+
+//    Copyright (C) 1993  University of Twente
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#include        <cstring>
+#include	<iostream>
+
+#include	"poly.h"
+#include	"poly_io.h"
+#include	"nclip.h"
+
+using
+  namespace::std;
+
+void
+clear (PolyPList & l)
+{
+  PolyPListIter
+  i (l);
+  while (i ())
+    delete
+      i.
+    val ();
+}
+
+int
+main (int, char *[])
+{
+  Poly *
+    a = read_poly (cin), *b = read_poly (cin);
+  PolyPList
+    a_min_b,
+    b_min_a,
+    a_and_b;
+
+  // printf("Area a %g b %g\n", a->area(), b->area());
+
+  clip_poly (*a, *b, a_min_b, b_min_a, a_and_b);
+
+  cout << "a_min_b:\n" << a_min_b;
+  cout << "b_min_a:\n" << b_min_a;
+  cout << "a_and_b:\n" << a_and_b;
+
+  delete
+    a;
+  delete
+    b;
+
+  clear (a_min_b);
+  clear (b_min_a);
+  clear (a_and_b);
+
+  return 0;
+}
--- /dev/null
+++ clippoly-0.11/configure.ac
@@ -0,0 +1,41 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.71])
+AC_INIT([polygon clipping library],[0.11],[klamer@mi.el.utwente.nl],[clippoly],[//http://clippoly.sourceforge.net])
+AM_INIT_AUTOMAKE([subdir-objects foreign -Wall])
+AC_CONFIG_SRCDIR([poly_io.cc])
+AC_CONFIG_HEADERS([config.h])
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_INSTALL
+AM_PROG_AR
+
+LT_INIT
+
+PKG_INSTALLDIR
+
+# Checks for header files.
+AC_CHECK_HEADERS([float.h malloc.h stdlib.h string.h])
+
+AC_CONFIG_MACRO_DIR([m4])
+
+AC_LANG([C++])
+
+AX_CFLAGS_WARN_ALL
+AX_CXXFLAGS_WARN_ALL
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_INLINE
+AC_HEADER_STDBOOL
+
+# Checks for library functions.
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_MALLOC
+AC_SEARCH_LIBS([hypot],[m])
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
--- clippoly-0.11.orig/graphadd.3
+++ clippoly-0.11/graphadd.3
@@ -1,65 +1,65 @@
-.TH GRAPHADD 3 "9 September 1992"
-.SH NAME
-v_print2, v_print3, m_print2, m_print3, v_scan2, v_scan3,  v_inters2, v_dupl2, v_dupl3, m_dupl2,  m_dupl3 \- additional 3d graphics and associated matrix and vector routines
-.nf
-.SH SYNOPSIS
-.nf
-.B #include <graphadd.h>
-.LP
-.B void		v_print2(hvec2_t vec, const char *name)
-
-.B void		v_print3(hvec3_t vec, const char *name)
-
-.B void		m_print2(hmat2_t mat, const char *name)
-
-.B void		m_print3(hmat3_t mat, const char *name)
-
-.B int          v_scan2(hvec2_t &vec)
-
-.B int          v_scan3(hvec3_t &vec)
-
-.B int v_inters2( 
-const hvec2_t &p1, const hvec2_t &p2, const hvec2_t &q1, 
-const hvec2_t &q2, hvec2_t *S1, hvec2_t *S2)
-
-.B void    v_dupl2(hvec2_t *, hvec2_t *)
-
-.B void    v_dupl3(hvec3_t *, hvec3_t *)
-
-.B void    m_dupl2(hmat2_t *, hmat2_t *)
-
-.B void    m_dupl3(hmat3_t *, hmat3_t *)
-
-.SH DESCRIPTION
-These routines ar an addition to grapmat(3). The *print routines print
-the approriate data to 
-.I stderr. 
-The *scan routines read from
-.I stdin.
-The *dupl routines copy data. v_inters2 returns the intersection point
-of p1,p2 and q1,q2 in S1 and S2. The return value is 0 if no intersection
-point is found, 1 if there is an intersection point, and two if the
-two lines do overlap. In that case, the two points are the extrema.
-
-.SH NAMES
-Naming conventions as in graphmat(3).
-
-.SH USAGE
-All the "functions" may have been implemented as macro's, so you can't
-take the address of a function. It is however guaranteed that arguments 
-of each function/macro will be evaluated only once, except for the result
-argument, which can be evaluated multiple times.
-
-.SH SEE ALSO
-graphmat(3), graphmat++(3), Graphics and matrix routines.
-
-.SH NOTE
-Only available in C++ and ANSI C. v_inters2 only in C++.
-Library file is
-.B /usr/local/lib/libgraphmat.a
-and the C++ util files.
-
-.SH AUTHOR
-Herbert Hilhorst
-.br
-Klamer Schutte
+.TH GRAPHADD 3 "9 September 1992"
+.SH NAME
+v_print2, v_print3, m_print2, m_print3, v_scan2, v_scan3,  v_inters2, v_dupl2, v_dupl3, m_dupl2,  m_dupl3 \- additional 3d graphics and associated matrix and vector routines
+.nf
+.SH SYNOPSIS
+.nf
+.B #include <graphadd.h>
+.LP
+.B void		v_print2(hvec2_t vec, const char *name)
+
+.B void		v_print3(hvec3_t vec, const char *name)
+
+.B void		m_print2(hmat2_t mat, const char *name)
+
+.B void		m_print3(hmat3_t mat, const char *name)
+
+.B int          v_scan2(hvec2_t &vec)
+
+.B int          v_scan3(hvec3_t &vec)
+
+.B int v_inters2( 
+const hvec2_t &p1, const hvec2_t &p2, const hvec2_t &q1, 
+const hvec2_t &q2, hvec2_t *S1, hvec2_t *S2)
+
+.B void    v_dupl2(hvec2_t *, hvec2_t *)
+
+.B void    v_dupl3(hvec3_t *, hvec3_t *)
+
+.B void    m_dupl2(hmat2_t *, hmat2_t *)
+
+.B void    m_dupl3(hmat3_t *, hmat3_t *)
+
+.SH DESCRIPTION
+These routines ar an addition to grapmat(3). The *print routines print
+the appropriate data to 
+.I stderr. 
+The *scan routines read from
+.I stdin.
+The *dupl routines copy data. v_inters2 returns the intersection point
+of p1,p2 and q1,q2 in S1 and S2. The return value is 0 if no intersection
+point is found, 1 if there is an intersection point, and two if the
+two lines do overlap. In that case, the two points are the extrema.
+
+.SH NAMES
+Naming conventions as in graphmat(3).
+
+.SH USAGE
+All the "functions" may have been implemented as macro's, so you can't
+take the address of a function. It is however guaranteed that arguments 
+of each function/macro will be evaluated only once, except for the result
+argument, which can be evaluated multiple times.
+
+.SH SEE ALSO
+graphmat(3), graphmat++(3), Graphics and matrix routines.
+
+.SH NOTE
+Only available in C++ and ANSI C. v_inters2 only in C++.
+Library file is
+.B /usr/local/lib/libgraphmat.a
+and the C++ util files.
+
+.SH AUTHOR
+Herbert Hilhorst
+.br
+Klamer Schutte
--- clippoly-0.11.orig/graphadd.cc
+++ clippoly-0.11/graphadd.cc
@@ -1,450 +1,493 @@
-static const char rcs_id[] = "$Header: /cvsroot/clippoly/clippoly/graphadd.cc,v 1.5 2005/02/28 17:21:12 klamer Exp $";
-
-//    tutvis library
-
-//    Copyright (C) 1993  University of Twente
-
-//    klamer@mi.el.utwente.nl
-
-//    This library is free software; you can redistribute it and/or
-//    modify it under the terms of the GNU Library General Public
-//    License as published by the Free Software Foundation; either
-//    version 2 of the License, or (at your option) any later version.
-
-//    This library is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//    Library General Public License for more details.
-
-//    You should have received a copy of the GNU Library General Public
-//    License along with this library; if not, write to the Free
-//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-// $Log: graphadd.cc,v $
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.1  1994/01/04  12:55:37  klamer
-// Initial revision
-//
-// Revision 1.6  1993/01/18  16:19:46  klamer
-// Fixed bug in swapping d1 and d2.
-//
-// Revision 1.5  1992/10/20  10:54:07  klamer
-// Made comparisons accurate.
-// Made in points const references.
-//
-// Revision 1.4  1992/09/16  15:54:07  klamer
-// Fixed bug for parallel lines...
-//
-// Revision 1.3  1992/09/11  14:51:38  klamer
-// Numerical more stable algorithm used.
-//
-// Revision 1.2  1992/09/09  15:49:10  klamer
-// split C and C++ parts.
-//
-//
-// 				     GRAPHADD.CC
-//
-//
-// author        : G.H.J. Hilhorst
-//
-// created       : 16-04-1992
-// last modified : 17-08-1992
-//
-
-#include	<assert.h>
-
-#include "graphadd.h"
-#include <graphmat++.h>
-
-static const char h_rcs_id[] = "$Header";
-
-#define Dabs(x) (((x)<0) ? (-(x)):(x))
-
-#ifndef EPSILON
-#define EPSILON          1e-10
-#endif
-
-#ifdef notdef
-#define Pos_cmp(pos1,pos2) (Dabs((pos1)-(pos2))<EPSILON)
-#define	ChkZero(x)		(Dabs(x) < EPSILON)
-#else
-#define Pos_cmp(pos1,pos2)	((pos1) == (pos2))
-#define	ChkZero(x)		(x == 0.0)
-#endif
-
-inline int
-  operator==( const hvec2_t &h1, const hvec2_t &h2 )
-{
-  return (v_x(h1) == v_x(h2)) && (v_y(h1) == v_y(h2));
-}
-
-inline int
-  operator!=( const hvec2_t &h1, const hvec2_t &h2 )
-{
-  return (v_x(h1) != v_x(h2)) || (v_y(h1) != v_y(h2));
-}
-
-inline double
-  max(double x, double y)
-{
-  return x > y ? x : y;
-}
-
-inline double
-  min(double x, double y)
-{
-  return x < y ? x : y;
-}
-
-static 
-#ifdef __GNUG__
-inline double
-m_len( const hvec2_t &v )
-#else
-double m_len( const hvec2_t v )
-#endif
-{
-	if (v_x(v) > 0)
-		return len( v );
-	if (v_x(v) < 0)
-		return -len( v );
-	if (v_y(v) > 0)
-		return len(v);
-	return -len(v);
-}
-
-static inline double
-  inp_ort( const hvec2_t &a, const hvec2_t &b )
-{
-  return v_x(a) * v_y(b) - v_y(a) * v_x(b);
-}
-
-static void	
-  recursive_intersection( const hvec2_t &p1, const hvec2_t &p2, 
-			 const hvec2_t & q1, const hvec2_t &q2, hvec2_t &ret )
-{
-  // Find intersection point of p1-p2 and q1-q2 by iteratively
-  // taking the middle of p1-p2
-  
-  hvec2_t	q = q2 - q1;
-  
-  if (len(q) < len(p2 - p1))
-  {
-    recursive_intersection(q1,q2,p1,p2,ret);
-    return;
-  }
-  
-  hvec2_t	s1 = p1 - q1, s2 = p2 - q1;
-  hvec2_t	m = (s1 + s2) / 2.0;
-  
-  double	inp = inp_ort( q, s1 );
-  
-  if (inp > 0)
-  {
-      hvec2_t	tmp = s1;
-      s1 = s2;
-      s2 = tmp;
-  }
-
-  while ((m != s1) && (m != s2))
-  {
-    assert(inp_ort(q,s1) <= 0);
-    assert(inp_ort(q,s2) >= 0);
-#ifdef notdef
-    hvec2_t	mp = m + q1 - p1, q1p = q1 - p1, q2p = q2 - p1;
-    assert(inp_ort(mp,q1p) * inp_ort(mp,q2p) <= 0);
-    mp = m + q1 - p2, q1p = q1 - p2, q2p = q2 - p2;
-    assert(inp_ort(mp,q1p) * inp_ort(mp,q2p) <= 0);
-#else
-    // assert(len(m) <= len(q2 - q1));
-    // assert(len(m+q1 - q2) <= len(q2 - q1));
-#endif
-    if (inp_ort(q,m) <= 0)
-      s1 = m;
-    else
-      s2 = m;
-    
-    m = (s1 + s2) / 2.0;
-  }
-    assert(len(m) <= len(q2 - q1));
-    assert(len(m+q1 - q2) <= len(q2 - q1));
-  
-  ret = m + q1;
-  
-  return;
-}
-
-int v_inters2(
-	const hvec2_t &p1,
-	const hvec2_t &p2,
-	const hvec2_t &q1,
-	const hvec2_t &q2,
-	hvec2_t *S1,
-	hvec2_t *S2
-	)
-/*******************************************************************
-*
-*  procedure that calculates the intersection point of point pair p
-*            and point pair q. It returns if they hit each other and
-*            the position of the hit(s) (S1 (and S2))
-*
-*******************************************************************/
-{
-	double rpx, rpy, rqx, rqy, t, deel, c1, c2, d1, d2, h;
-	hvec2_t // normal,
-		hv,hp1,hq1,hp2,hq2;
-
-	if (max(v_x(p1),v_x(p2)) < min(v_x(q1),v_x(q2)))
-	  return 0;
-	if (max(v_x(q1),v_x(q2)) < min(v_x(p1),v_x(p2)))
-	  return 0;
-	
-	rpx=v_x(p2)-v_x(p1);
-	rpy=v_y(p2)-v_y(p1);
-	rqx=v_x(q2)-v_x(q1);
-	rqy=v_y(q2)-v_y(q1);
-
-	deel=rpx*rqy-rpy*rqx;
-// every value below EPSILON is considered as being 0. Hence, we do not intro-
-// duce numerical inaccuracies
-	// if (deel == 0) // 
-	//if(Dabs(deel)<EPSILON)	/* parallel */
-	if(ChkZero(deel))	/* parallel */
-	{
-#ifdef notdef
-	// This might fail if the intersection point is far away!
-
-	  if(rpy!=0)
-	  {
-	    if(rqy!=0)
-	    {	// Check intersection points on X axis of lines
-	     if(!Pos_cmp(v_x(p1)-v_y(p1)*rpx/rpy,v_x(q1)-v_y(q1)*rqx/rqy))
-		 return(0);
-	    } else if(!Pos_cmp(v_x(p1),v_x(q1)+(v_y(p1)-v_y(q1))/rqy*rqx))
-		 return(0);
-	  } else
-	  { /* rpy=0 */
-	    if(rpx!=0)
-	    {
-	      if(Pos_cmp(v_y(p1)-v_x(p1)*rpy/rpx,v_y(q1)-v_x(q1)*rqy/rqx))
-		return(0);
-	    } else if(!Pos_cmp(v_y(p1),v_y(q1)+(v_x(p1)-v_x(q1))/rqx*rqy))
-		return(0);
-	  }
-#else
-		// Check too see whether p1-p2 and q1-q2 are on the same line
-
-		hvec2_t	q1p1, q1q2;
-
-		vv_sub2( &q1, &p1, &q1p1 );
-		vv_sub2( &q1, &q2, &q1q2 );
-
-		// double inpr = vv_inprod2( &q1p1, &q1q2 );
-		double	inpr = v_x(q1p1)*v_y(q1q2) - v_y(q1p1) * v_x(q1q2);
-
-		// If this product is not zero then p1 is not on q1-q2!
-		// if (inpr != 0) // 
-		//if (!(Dabs(inpr)<EPSILON))	
-		if (!ChkZero(inpr))
-			return 0;
-#endif
-
-#ifdef notdef
-		// This will fail if the origin is on (or close to) the line!
-
-		vv_sub2(&p2, &p1, &normal);
-		c1= vv_inprod2(&normal, &p1);  /* assume W=0 */
-		c2= vv_inprod2(&normal, &p2);
-		d1= vv_inprod2(&normal, &q1);
-		d2= vv_inprod2(&normal, &q2);
-#else
-		c1 = 0;		// m_len(p1 - p1)
-		c2 = m_len(p1 - p2);
-		d1 = m_len(p1 - q1);
-		d2 = m_len(p1 - q2);
-#endif
-  
-/* Sorting the independent points from small to large: */
-		v_cpy2(&p1,&hp1);
-		v_cpy2(&p2,&hp2);
-		v_cpy2(&q1,&hq1);
-		v_cpy2(&q2,&hq2);
-		if (c1>c2)
-		{		/* hv and h are used as help-variable. */
-			v_cpy2(&hp1,&hv);
-			v_cpy2(&hp2,&hp1);
-			v_cpy2(&hv,&hp2);
-			h=c1;		 c1=c2;		  c2=h;
-		}
-		if (d1>d2)
-		{
-			v_cpy2(&hq1,&hv);
-			v_cpy2(&hq2,&hq1);
-			v_cpy2(&hv,&hq2);
-			h=d1;		 d1=d2;		  d2=h;
-		}
-
-/* Now the line-pieces are compared: */
-
-		if (c1<d1)
-		{
-			if (c2<d1) return 0;
-			if (c2<d2)	{ v_cpy2(&hp2,S1); v_cpy2(&hq1,S2); }
-			else		{ v_cpy2(&hq1,S1); v_cpy2(&hq2,S2); };
-		}
- 		else
-    		{
-			if (c1>d2) return 0;
-     	 		if (c2<d2)	{ v_cpy2(&hp1,S1); v_cpy2(&hp2,S2); }
-     	 		else	        { v_cpy2(&hp1,S1); v_cpy2(&hq2,S2); };
-		}
-
-		if((v_x(*S1)==v_x(*S2)) && (v_y(*S1)==v_y(*S2))) return(1);
-		else return(2);
-	}
-	else	/* not parallel */
-	{
-/*
- * We have the lines:
- * l1: p1 + s(p2 - p1)
- * l2: q1 + t(q2 - q1)
- * And we want to know the intersection point.
- * Calculate t:
- * p1 + s(p2-p1) = q1 + t(q2-q1)
- * which is similar to the two equations:
- * p1x + s * rpx = q1x + t * rqx
- * p1y + s * rpy = q1y + t * rqy
- * Multiplying these by rpy resp. rpx gives:
- * rpy * p1x + s * rpx * rpy = rpy * q1x + t * rpy * rqx
- * rpx * p1y + s * rpx * rpy = rpx * q1y + t * rpx * rqy
- * Subtracting these gives:
- * rpy * p1x - rpx * p1y = rpy * q1x - rpx * q1y + t * ( rpy * rqx - rpx * rqy )
- * So t can be isolated:
- * t = (rpy * ( p1x - q1x ) + rpx * ( - p1y + q1y )) / ( rpy * rqx - rpx * rqy )
- * and deel = rpx * rqy - rpy * rqx
- */
-	  	if ((q1 == p1) || (q1 == p2))
-		  *S1 = q1;
-		else if ((q2 == p1) || (q2 == p2))
-		  *S1 = q2;
-		else {
-		  t=-(rpy*(-v_x(q1)+v_x(p1))+rpx*(v_y(q1)-v_y(p1)))/deel;
-		  v_x(*S1) = v_x(q1)+t*rqx;
-		  v_y(*S1) = v_y(q1)+t*rqy;
-	  	  v_w(*S1) = 1;
-		}
-
-#ifdef notdef
-		// Say that *S1 equals one of the points if the relative distance is smaller
-		// than EPSILON
-		double	l_p = len(p1 - p2);
-		if (EPSILON > len(*S1 - p2) / l_p)
-		  *S1 = p2;
-		else if (EPSILON > len(*S1 - p1) / l_p)
-		  *S1 = p1;
-		else {
-		  double	l_q = len(q1 - q2);
-		  if (EPSILON > len(*S1 - q2) / l_q)
-		  *S1 = q2;
-		else if (EPSILON > len(*S1 - q1) / l_q)
-		  *S1 = q1;
-		}
-#endif
-	
-/*
- * The intersection point is valid if it is
- * 1) on q1-q2 --> t >= 0 && t <= 1
- * 2) on p1-p2 --> p1 must be on the other side of q1-q2 as p2
- *    This is so if the difference of the x coordinate of p1-s1 has the
- *    opposite sign as the x coordinate of p2-s2. So the multiplication of
- *    these two must be negative. This might fail if p1-p2 is a vertical line;
- *    this can be solved by adding the same product for the y coordinates
- */
-#ifdef notdef
-		return((t>=0) && (t<=1) &&
-			((v_x(*S1)-v_x(p1))*(v_x(*S1)-v_x(p2))+
-			 (v_y(*S1)-v_y(p1))*(v_y(*S1)-v_y(p2))<=0) );
-#else
-#ifdef notdef
-		int	condition = ((t>=0) && (t<=1) &&
-			((v_x(*S1)-v_x(p1))*(v_x(*S1)-v_x(p2))+
-			 (v_y(*S1)-v_y(p1))*(v_y(*S1)-v_y(p2))<=0) );
-#endif
-		
-		// Implement an other way of checking whether the calculated point is valid.
-		// This is done using the inproduct on the original points.
-		hvec2_t	p = p2 - p1, pq1 = q1 - p1, pq2 = q2 - p1;
-		double	inp1 = v_x(p) * v_y(pq1) - v_y(p) * v_x(pq1),
-			inp2 = v_x(p) * v_y(pq2) - v_y(p) * v_x(pq2);
-		int	c1 = inp1 * inp2 <= 0;
-
-		hvec2_t	q = q2 - q1, qp1 = p1 - q1, qp2 = p2 - q1;
-		double	inp3 = v_x(q) * v_y(qp1) - v_y(q) * v_x(qp1),
-			inp4 = v_x(q) * v_y(qp2) - v_y(q) * v_x(qp2);
-		int	c2 = inp3 * inp4 <= 0;
-
-		//if (c1 && c2 && 0)
-		{
-		  // Say that *S1 equals one of the points if the relative distance is smaller
-		  // than EPSILON
-		  double	l_q = len(q1 - q2);
-		  double	l_p = len(p1 - p2);
-		  if (EPSILON > len(*S1 - p2) / l_p)
-		    { *S1 = p2; c2 = 2; }
-		  else if (EPSILON > len(*S1 - p1) / l_p)
-		    { *S1 = p1; c2 = 2; }
-		  else {
-		    // double	l_q = len(q1 - q2);
-		    if (EPSILON > len(*S1 - q2) / l_q)
-		      { *S1 = q2; c1 = 2; }
-		    else if (EPSILON > len(*S1 - q1) / l_q)
-		      { *S1 = q1; c1 = 2; }
-		  }
-		}
-		
-		hvec2_t	s = *S1 - p1;
-		double	inp1s = v_x(s) * v_y(pq1) - v_y(s) * v_x(pq1),
-			inp2s = v_x(s) * v_y(pq2) - v_y(s) * v_x(pq2);
-		int	c1s = (*S1 == p1) ? -1 : inp1s * inp2s <= 0;
-
-		hvec2_t	qs = *S1 - q1;
-		double	inp3s = v_x(qs) * v_y(qp1) - v_y(qs) * v_x(qp1),
-			inp4s = v_x(qs) * v_y(qp2) - v_y(qs) * v_x(qp2);
-		int	c2s = (*S1 == q1) ? -1 : inp3s * inp4s <= 0;
-
-		// Roundig errors might make the statements below untrue
-		int	failed = 0;
-		if (!((c1 == 0) || (c2 == 0) || (c1s == (c1 != 0)) || (c1s == -1)))
-		  failed = 1;
-		else if (!((c1 == 0) || (c2 == 0) || (c2s == (c2 != 0)) || (c2s == -1)))
-		  failed = 2;
-		else if (c1 && c2 && (len(*S1 - q1) > len(q2 - q1)))
-		  failed = 3;
-		else if (c1 && c2 && (len(*S1 - q2) > len(q2 - q1)))
-		  failed = 4;
-		else if (c1 && c2 && (len(*S1 - p1) > len(p2 - p1)))
-		  failed = 5;
-		else if (c1 && c2 && (len(*S1 - p2) > len(p2 - p1)))
-		  failed = 6;
-		if ((failed >= 3) && (c1 == 2 || c2 == 2))
-		{
-		  failed = -1; c1 = c2 = 0;
-	 	}
-		if (failed > 0)
-		  recursive_intersection(p1, p2, q1, q2, *S1);
-#ifdef notdef
-		assert((c1 && c2) == condition);
-		
-		return condition;
-#else
-		return (c1 && c2);
-#endif
-#endif
-	}
-}
-
-
-
+//    tutvis library
+
+//    Copyright (C) 1993  University of Twente
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.1  1994/01/04  12:55:37  klamer
+// Initial revision
+//
+// Revision 1.6  1993/01/18  16:19:46  klamer
+// Fixed bug in swapping d1 and d2.
+//
+// Revision 1.5  1992/10/20  10:54:07  klamer
+// Made comparisons accurate.
+// Made in points const references.
+//
+// Revision 1.4  1992/09/16  15:54:07  klamer
+// Fixed bug for parallel lines...
+//
+// Revision 1.3  1992/09/11  14:51:38  klamer
+// Numerical more stable algorithm used.
+//
+// Revision 1.2  1992/09/09  15:49:10  klamer
+// split C and C++ parts.
+//
+//
+//                                   GRAPHADD.CC
+//
+//
+// author        : G.H.J. Hilhorst
+//
+// created       : 16-04-1992
+// last modified : 17-08-1992
+//
+
+#include	<assert.h>
+
+#include "graphadd.h"
+#include <graphmat++.h>
+
+#define Dabs(x) (((x)<0) ? (-(x)):(x))
+
+#ifndef EPSILON
+#define EPSILON          1e-10
+#endif
+
+#ifdef notdef
+#define Pos_cmp(pos1,pos2) (Dabs((pos1)-(pos2))<EPSILON)
+#define	ChkZero(x)		(Dabs(x) < EPSILON)
+#else
+#define Pos_cmp(pos1,pos2)	((pos1) == (pos2))
+#define	ChkZero(x)		(x == 0.0)
+#endif
+
+inline int
+operator== (const hvec2_t & h1, const hvec2_t & h2)
+{
+  return (v_x (h1) == v_x (h2)) && (v_y (h1) == v_y (h2));
+}
+
+inline int
+operator!= (const hvec2_t & h1, const hvec2_t & h2)
+{
+  return (v_x (h1) != v_x (h2)) || (v_y (h1) != v_y (h2));
+}
+
+inline double
+max (double x, double y)
+{
+  return x > y ? x : y;
+}
+
+inline double
+min (double x, double y)
+{
+  return x < y ? x : y;
+}
+
+static
+#ifdef __GNUG__
+  inline double
+m_len (const hvec2_t & v)
+#else
+  double
+m_len (const hvec2_t v)
+#endif
+{
+  if (v_x (v) > 0)
+    return len (v);
+  if (v_x (v) < 0)
+    return -len (v);
+  if (v_y (v) > 0)
+    return len (v);
+  return -len (v);
+}
+
+static inline double
+inp_ort (const hvec2_t & a, const hvec2_t & b)
+{
+  return v_x (a) * v_y (b) - v_y (a) * v_x (b);
+}
+
+static void
+recursive_intersection (const hvec2_t & p1, const hvec2_t & p2,
+			const hvec2_t & q1, const hvec2_t & q2, hvec2_t & ret)
+{
+  // Find intersection point of p1-p2 and q1-q2 by iteratively
+  // taking the middle of p1-p2
+
+  hvec2_t q = q2 - q1;
+
+  if (len (q) < len (p2 - p1))
+    {
+      recursive_intersection (q1, q2, p1, p2, ret);
+      return;
+    }
+
+  hvec2_t s1 = p1 - q1, s2 = p2 - q1;
+  hvec2_t m = (s1 + s2) / 2.0;
+
+  double inp = inp_ort (q, s1);
+
+  if (inp > 0)
+    {
+      hvec2_t tmp = s1;
+      s1 = s2;
+      s2 = tmp;
+    }
+
+  while ((m != s1) && (m != s2))
+    {
+      assert (inp_ort (q, s1) <= 0);
+      assert (inp_ort (q, s2) >= 0);
+#ifdef notdef
+      hvec2_t mp = m + q1 - p1, q1p = q1 - p1, q2p = q2 - p1;
+      assert (inp_ort (mp, q1p) * inp_ort (mp, q2p) <= 0);
+      mp = m + q1 - p2, q1p = q1 - p2, q2p = q2 - p2;
+      assert (inp_ort (mp, q1p) * inp_ort (mp, q2p) <= 0);
+#else
+      // assert(len(m) <= len(q2 - q1));
+      // assert(len(m+q1 - q2) <= len(q2 - q1));
+#endif
+      if (inp_ort (q, m) <= 0)
+	s1 = m;
+      else
+	s2 = m;
+
+      m = (s1 + s2) / 2.0;
+    }
+  assert (len (m) <= len (q2 - q1));
+  assert (len (m + q1 - q2) <= len (q2 - q1));
+
+  ret = m + q1;
+
+  return;
+}
+
+int
+v_inters2 (const hvec2_t & p1,
+	   const hvec2_t & p2,
+	   const hvec2_t & q1, const hvec2_t & q2, hvec2_t *S1, hvec2_t *S2)
+/*******************************************************************
+*
+*  procedure that calculates the intersection point of point pair p
+*            and point pair q. It returns if they hit each other and
+*            the position of the hit(s) (S1 (and S2))
+*
+*******************************************************************/
+{
+  double rpx, rpy, rqx, rqy, t, deel, c1, c2, d1, d2, h;
+  hvec2_t			// normal,
+    hv, hp1, hq1, hp2, hq2;
+
+  if (max (v_x (p1), v_x (p2)) < min (v_x (q1), v_x (q2)))
+    return 0;
+  if (max (v_x (q1), v_x (q2)) < min (v_x (p1), v_x (p2)))
+    return 0;
+
+  rpx = v_x (p2) - v_x (p1);
+  rpy = v_y (p2) - v_y (p1);
+  rqx = v_x (q2) - v_x (q1);
+  rqy = v_y (q2) - v_y (q1);
+
+  deel = rpx * rqy - rpy * rqx;
+// every value below EPSILON is considered as being 0. Hence, we do not intro-
+// duce numerical inaccuracies
+  // if (deel == 0) //
+  //if(Dabs(deel)<EPSILON)        /* parallel */
+  if (ChkZero (deel))		/* parallel */
+    {
+#ifdef notdef
+      // This might fail if the intersection point is far away!
+
+      if (rpy != 0)
+	{
+	  if (rqy != 0)
+	    {			// Check intersection points on X axis of lines
+	      if (!Pos_cmp
+		  (v_x (p1) - v_y (p1) * rpx / rpy,
+		   v_x (q1) - v_y (q1) * rqx / rqy))
+		return (0);
+	    }
+	  else
+	    if (!Pos_cmp
+		(v_x (p1), v_x (q1) + (v_y (p1) - v_y (q1)) / rqy * rqx))
+	    return (0);
+	}
+      else
+	{			/* rpy=0 */
+	  if (rpx != 0)
+	    {
+	      if (Pos_cmp
+		  (v_y (p1) - v_x (p1) * rpy / rpx,
+		   v_y (q1) - v_x (q1) * rqy / rqx))
+		return (0);
+	    }
+	  else
+	    if (!Pos_cmp
+		(v_y (p1), v_y (q1) + (v_x (p1) - v_x (q1)) / rqx * rqy))
+	    return (0);
+	}
+#else
+      // Check too see whether p1-p2 and q1-q2 are on the same line
+
+      hvec2_t q1p1, q1q2;
+
+      vv_sub2 (&q1, &p1, &q1p1);
+      vv_sub2 (&q1, &q2, &q1q2);
+
+      // double inpr = vv_inprod2( &q1p1, &q1q2 );
+      double inpr = v_x (q1p1) * v_y (q1q2) - v_y (q1p1) * v_x (q1q2);
+
+      // If this product is not zero then p1 is not on q1-q2!
+      // if (inpr != 0) //
+      //if (!(Dabs(inpr)<EPSILON))
+      if (!ChkZero (inpr))
+	return 0;
+#endif
+
+#ifdef notdef
+      // This will fail if the origin is on (or close to) the line!
+
+      vv_sub2 (&p2, &p1, &normal);
+      c1 = vv_inprod2 (&normal, &p1);	/* assume W=0 */
+      c2 = vv_inprod2 (&normal, &p2);
+      d1 = vv_inprod2 (&normal, &q1);
+      d2 = vv_inprod2 (&normal, &q2);
+#else
+      c1 = 0;			// m_len(p1 - p1)
+      c2 = m_len (p1 - p2);
+      d1 = m_len (p1 - q1);
+      d2 = m_len (p1 - q2);
+#endif
+
+/* Sorting the independent points from small to large: */
+      v_cpy2 (&p1, &hp1);
+      v_cpy2 (&p2, &hp2);
+      v_cpy2 (&q1, &hq1);
+      v_cpy2 (&q2, &hq2);
+      if (c1 > c2)
+	{			/* hv and h are used as help-variable. */
+	  v_cpy2 (&hp1, &hv);
+	  v_cpy2 (&hp2, &hp1);
+	  v_cpy2 (&hv, &hp2);
+	  h = c1;
+	  c1 = c2;
+	  c2 = h;
+	}
+      if (d1 > d2)
+	{
+	  v_cpy2 (&hq1, &hv);
+	  v_cpy2 (&hq2, &hq1);
+	  v_cpy2 (&hv, &hq2);
+	  h = d1;
+	  d1 = d2;
+	  d2 = h;
+	}
+
+/* Now the line-pieces are compared: */
+
+      if (c1 < d1)
+	{
+	  if (c2 < d1)
+	    return 0;
+	  if (c2 < d2)
+	    {
+	      v_cpy2 (&hp2, S1);
+	      v_cpy2 (&hq1, S2);
+	    }
+	  else
+	    {
+	      v_cpy2 (&hq1, S1);
+	      v_cpy2 (&hq2, S2);
+	    };
+	}
+      else
+	{
+	  if (c1 > d2)
+	    return 0;
+	  if (c2 < d2)
+	    {
+	      v_cpy2 (&hp1, S1);
+	      v_cpy2 (&hp2, S2);
+	    }
+	  else
+	    {
+	      v_cpy2 (&hp1, S1);
+	      v_cpy2 (&hq2, S2);
+	    };
+	}
+
+      if ((v_x (*S1) == v_x (*S2)) && (v_y (*S1) == v_y (*S2)))
+	return (1);
+      else
+	return (2);
+    }
+  else				/* not parallel */
+    {
+/*
+ * We have the lines:
+ * l1: p1 + s(p2 - p1)
+ * l2: q1 + t(q2 - q1)
+ * And we want to know the intersection point.
+ * Calculate t:
+ * p1 + s(p2-p1) = q1 + t(q2-q1)
+ * which is similar to the two equations:
+ * p1x + s * rpx = q1x + t * rqx
+ * p1y + s * rpy = q1y + t * rqy
+ * Multiplying these by rpy resp. rpx gives:
+ * rpy * p1x + s * rpx * rpy = rpy * q1x + t * rpy * rqx
+ * rpx * p1y + s * rpx * rpy = rpx * q1y + t * rpx * rqy
+ * Subtracting these gives:
+ * rpy * p1x - rpx * p1y = rpy * q1x - rpx * q1y + t * ( rpy * rqx - rpx * rqy )
+ * So t can be isolated:
+ * t = (rpy * ( p1x - q1x ) + rpx * ( - p1y + q1y )) / ( rpy * rqx - rpx * rqy )
+ * and deel = rpx * rqy - rpy * rqx
+ */
+      if ((q1 == p1) || (q1 == p2))
+	*S1 = q1;
+      else if ((q2 == p1) || (q2 == p2))
+	*S1 = q2;
+      else
+	{
+	  t =
+	    -(rpy * (-v_x (q1) + v_x (p1)) +
+	      rpx * (v_y (q1) - v_y (p1))) / deel;
+	  v_x (*S1) = v_x (q1) + t * rqx;
+	  v_y (*S1) = v_y (q1) + t * rqy;
+	  v_w (*S1) = 1;
+	}
+
+#ifdef notdef
+      // Say that *S1 equals one of the points if the relative distance is smaller
+      // than EPSILON
+      double l_p = len (p1 - p2);
+      if (EPSILON > len (*S1 - p2) / l_p)
+	*S1 = p2;
+      else if (EPSILON > len (*S1 - p1) / l_p)
+	*S1 = p1;
+      else
+	{
+	  double l_q = len (q1 - q2);
+	  if (EPSILON > len (*S1 - q2) / l_q)
+	    *S1 = q2;
+	  else if (EPSILON > len (*S1 - q1) / l_q)
+	    *S1 = q1;
+	}
+#endif
+
+/*
+ * The intersection point is valid if it is
+ * 1) on q1-q2 --> t >= 0 && t <= 1
+ * 2) on p1-p2 --> p1 must be on the other side of q1-q2 as p2
+ *    This is so if the difference of the x coordinate of p1-s1 has the
+ *    opposite sign as the x coordinate of p2-s2. So the multiplication of
+ *    these two must be negative. This might fail if p1-p2 is a vertical line;
+ *    this can be solved by adding the same product for the y coordinates
+ */
+#ifdef notdef
+      return ((t >= 0) && (t <= 1) &&
+	      ((v_x (*S1) - v_x (p1)) * (v_x (*S1) - v_x (p2)) +
+	       (v_y (*S1) - v_y (p1)) * (v_y (*S1) - v_y (p2)) <= 0));
+#else
+#ifdef notdef
+      int condition = ((t >= 0) && (t <= 1) &&
+		       ((v_x (*S1) - v_x (p1)) * (v_x (*S1) - v_x (p2)) +
+			(v_y (*S1) - v_y (p1)) * (v_y (*S1) - v_y (p2)) <=
+			0));
+#endif
+
+      // Implement an other way of checking whether the calculated point is valid.
+      // This is done using the inproduct on the original points.
+      hvec2_t p = p2 - p1, pq1 = q1 - p1, pq2 = q2 - p1;
+      double inp1 = v_x (p) * v_y (pq1) - v_y (p) * v_x (pq1),
+	inp2 = v_x (p) * v_y (pq2) - v_y (p) * v_x (pq2);
+      int c1 = inp1 * inp2 <= 0;
+
+      hvec2_t q = q2 - q1, qp1 = p1 - q1, qp2 = p2 - q1;
+      double inp3 = v_x (q) * v_y (qp1) - v_y (q) * v_x (qp1),
+	inp4 = v_x (q) * v_y (qp2) - v_y (q) * v_x (qp2);
+      int c2 = inp3 * inp4 <= 0;
+
+      //if (c1 && c2 && 0)
+      {
+	// Say that *S1 equals one of the points if the relative distance is smaller
+	// than EPSILON
+	double l_q = len (q1 - q2);
+	double l_p = len (p1 - p2);
+	if (EPSILON > len (*S1 - p2) / l_p)
+	  {
+	    *S1 = p2;
+	    c2 = 2;
+	  }
+	else if (EPSILON > len (*S1 - p1) / l_p)
+	  {
+	    *S1 = p1;
+	    c2 = 2;
+	  }
+	else
+	  {
+	    // double   l_q = len(q1 - q2);
+	    if (EPSILON > len (*S1 - q2) / l_q)
+	      {
+		*S1 = q2;
+		c1 = 2;
+	      }
+	    else if (EPSILON > len (*S1 - q1) / l_q)
+	      {
+		*S1 = q1;
+		c1 = 2;
+	      }
+	  }
+      }
+
+      hvec2_t s = *S1 - p1;
+      double inp1s = v_x (s) * v_y (pq1) - v_y (s) * v_x (pq1),
+	inp2s = v_x (s) * v_y (pq2) - v_y (s) * v_x (pq2);
+      int c1s = (*S1 == p1) ? -1 : inp1s * inp2s <= 0;
+
+      hvec2_t qs = *S1 - q1;
+      double inp3s = v_x (qs) * v_y (qp1) - v_y (qs) * v_x (qp1),
+	inp4s = v_x (qs) * v_y (qp2) - v_y (qs) * v_x (qp2);
+      int c2s = (*S1 == q1) ? -1 : inp3s * inp4s <= 0;
+
+      // Rounding errors might make the statements below untrue
+      int failed = 0;
+      if (!((c1 == 0) || (c2 == 0) || (c1s == (c1 != 0)) || (c1s == -1)))
+	failed = 1;
+      else if (!((c1 == 0) || (c2 == 0) || (c2s == (c2 != 0)) || (c2s == -1)))
+	failed = 2;
+      else if (c1 && c2 && (len (*S1 - q1) > len (q2 - q1)))
+	failed = 3;
+      else if (c1 && c2 && (len (*S1 - q2) > len (q2 - q1)))
+	failed = 4;
+      else if (c1 && c2 && (len (*S1 - p1) > len (p2 - p1)))
+	failed = 5;
+      else if (c1 && c2 && (len (*S1 - p2) > len (p2 - p1)))
+	failed = 6;
+      if ((failed >= 3) && (c1 == 2 || c2 == 2))
+	{
+	  failed = -1;
+	  c1 = c2 = 0;
+	}
+      if (failed > 0)
+	recursive_intersection (p1, p2, q1, q2, *S1);
+#ifdef notdef
+      assert ((c1 && c2) == condition);
+
+      return condition;
+#else
+      return (c1 && c2);
+#endif
+#endif
+    }
+}
--- clippoly-0.11.orig/graphadd.h
+++ clippoly-0.11/graphadd.h
@@ -1,112 +1,106 @@
-/*
- *    tutvis library
-
- *    Copyright (C) 1993  University of Twente
-
- *    klamer@mi.el.utwente.nl
-
- *    This library is free software; you can redistribute it and/or
- *    modify it under the terms of the GNU Library General Public
- *    License as published by the Free Software Foundation; either
- *    version 2 of the License, or (at your option) any later version.
-
- *    This library is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *    Library General Public License for more details.
-
- *    You should have received a copy of the GNU Library General Public
- *    License along with this library; if not, write to the Free
- *    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * $Log: graphadd.h,v $
- * Revision 1.7  2005/02/28 21:12:05  klamer
- * Made changes such that gcc 3.4.2 compiles silent with -ansi -pedantic -Wall.
- *
- * Revision 1.6  2005/02/28 17:26:49  klamer
- * Changed comment with $Log: graphadd.h,v $
- * Changed comment with Revision 1.7  2005/02/28 21:12:05  klamer
- * Changed comment with Made changes such that gcc 3.4.2 compiles silent with -ansi -pedantic -Wall.
- * Changed comment with to get rid of warning.
- *
- * Revision 1.5  2005/02/28 17:21:12  klamer
- * Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
- * Change use of (libg++) String to ANSI C++ string.
- *
- * Revision 1.3  1992/10/20  13:48:39  klamer
- * Made input arguments of v_inters const.
- *
-// Revision 1.2  1992/09/09  15:49:10  klamer
-// split C and C++ parts.
-// Added ANSI C support.
-//
-//
-// 				     GRAPHADD.H
-//
-//
-// author        : G.H.J. Hilhorst
-//
-// created       : 16-04-1992
-// last modified : 21-05-1992
-*/
-
-#ifndef GRAPHADD_H
-#define	GRAPHADD_H	"$Header: /cvsroot/clippoly/clippoly/graphadd.h,v 1.7 2005/02/28 21:12:05 klamer Exp $"
-
-#ifndef GRAPHMAT_INCLUDE
-#include	<graphmat.h>
-#endif
-
-#define	v_print2(vec,vec_name)(fprintf(stderr,"vec2 %s:\tx=%g\t y=%g\tw=%g\n",\
-	vec_name,v_x(vec),v_y(vec),v_w(vec)))
-
-#define	v_print3(vec,vec_name)(fprintf(stderr,\
-	"vec3 %s:\tx=%g\t y=%g\tz=%g\tw=%g\n",\
-	vec_name,v_x(vec),v_y(vec),v_z(vec),v_w(vec)))
-
-#define	m_print2(mat,vec_name) if(&(mat)!=NULL) fprintf(stderr, \
-	"mat2 %s:\n%g\t%g\t%g\n%g\t%g\t%g\n%g\t%g\t%g\n", \
-	vec_name,m_elem(mat,0,0),m_elem(mat,0,1),m_elem(mat,0,2), \
-	m_elem(mat,1,0),m_elem(mat,1,1),m_elem(mat,1,2), \
-	m_elem(mat,2,0),m_elem(mat,2,1),m_elem(mat,2,2))
-
-#define	m_print3(mat,vec_name) if(&(mat)!=NULL) fprintf(stderr, \
- "mat3 %s:\n%g\t%g\t%g\t%g\n%g\t%g\t%g\t%g\n%g\t%g\t%g\t%g\n%g\t%g\t%g\t%g\n",\
-     vec_name,m_elem(mat,0,0),m_elem(mat,0,1),m_elem(mat,0,2),m_elem(mat,0,3),\
-	m_elem(mat,1,0),m_elem(mat,1,1),m_elem(mat,1,2),m_elem(mat,1,3), \
-	m_elem(mat,2,0),m_elem(mat,2,1),m_elem(mat,2,2),m_elem(mat,2,3), \
-	m_elem(mat,3,0),m_elem(mat,3,1),m_elem(mat,3,2),m_elem(mat,3,3))
-
-#define v_scan2(vec)(scanf("%lf %lf %lf",&v_x(*vec),&v_y(*vec),&v_w(*vec)))
-
-#define v_scan3(vec)(scanf("%lf %lf %lf %lf",&v_x(*vec),&v_y(*vec),\
-	&v_z(*vec),&v_w(*vec)))
-
-#ifdef __cplusplus
-
-int v_inters2(
-	const hvec2_t &p1,
-	const hvec2_t &p2,
-	const hvec2_t &q1,
-	const hvec2_t &q2,
-	hvec2_t *S1,
-	hvec2_t *S2
-	);
-
-extern "C" {
-#endif
-
-
-void	v_dupl2(hvec2_t *, hvec2_t *);
-void	v_dupl3(hvec3_t *, hvec3_t *);
-void	m_dupl2(hmat2_t *, hmat2_t *);
-void	m_dupl3(hmat3_t *, hmat3_t *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
+/*
+ *    tutvis library
+
+ *    Copyright (C) 1993  University of Twente
+
+ *    klamer@mi.el.utwente.nl
+
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Library General Public
+ *    License as published by the Free Software Foundation; either
+ *    version 2 of the License, or (at your option) any later version.
+
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Library General Public License for more details.
+
+ *    You should have received a copy of the GNU Library General Public
+ *    License along with this library; if not, write to the Free
+ *    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Revision 1.7  2005/02/28 21:12:05  klamer
+ * Made changes such that gcc 3.4.2 compiles silent with -ansi -pedantic -Wall.
+ *
+ * Revision 1.6  2005/02/28 17:26:49  klamer
+ * Changed comment with Revision 1.7  2005/02/28 21:12:05  klamer
+ * Changed comment with Made changes such that gcc 3.4.2 compiles silent with -ansi -pedantic -Wall.
+ * Changed comment with to get rid of warning.
+ *
+ * Revision 1.5  2005/02/28 17:21:12  klamer
+ * Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+ * Change use of (libg++) String to ANSI C++ string.
+ *
+ * Revision 1.3  1992/10/20  13:48:39  klamer
+ * Made input arguments of v_inters const.
+ *
+// Revision 1.2  1992/09/09  15:49:10  klamer
+// split C and C++ parts.
+// Added ANSI C support.
+//
+//
+// 				     GRAPHADD.H
+//
+//
+// author        : G.H.J. Hilhorst
+//
+// created       : 16-04-1992
+// last modified : 21-05-1992
+*/
+
+#ifndef GRAPHADD_H
+#define	GRAPHADD_H
+
+#ifndef GRAPHMAT_INCLUDE
+#include	<graphmat.h>
+#endif
+
+#define	v_print2(vec,vec_name)(fprintf(stderr,"vec2 %s:\tx=%g\t y=%g\tw=%g\n",\
+	vec_name,v_x(vec),v_y(vec),v_w(vec)))
+
+#define	v_print3(vec,vec_name)(fprintf(stderr,\
+	"vec3 %s:\tx=%g\t y=%g\tz=%g\tw=%g\n",\
+	vec_name,v_x(vec),v_y(vec),v_z(vec),v_w(vec)))
+
+#define	m_print2(mat,vec_name) if(&(mat)!=NULL) fprintf(stderr, \
+	"mat2 %s:\n%g\t%g\t%g\n%g\t%g\t%g\n%g\t%g\t%g\n", \
+	vec_name,m_elem(mat,0,0),m_elem(mat,0,1),m_elem(mat,0,2), \
+	m_elem(mat,1,0),m_elem(mat,1,1),m_elem(mat,1,2), \
+	m_elem(mat,2,0),m_elem(mat,2,1),m_elem(mat,2,2))
+
+#define	m_print3(mat,vec_name) if(&(mat)!=NULL) fprintf(stderr, \
+ "mat3 %s:\n%g\t%g\t%g\t%g\n%g\t%g\t%g\t%g\n%g\t%g\t%g\t%g\n%g\t%g\t%g\t%g\n",\
+     vec_name,m_elem(mat,0,0),m_elem(mat,0,1),m_elem(mat,0,2),m_elem(mat,0,3),\
+	m_elem(mat,1,0),m_elem(mat,1,1),m_elem(mat,1,2),m_elem(mat,1,3), \
+	m_elem(mat,2,0),m_elem(mat,2,1),m_elem(mat,2,2),m_elem(mat,2,3), \
+	m_elem(mat,3,0),m_elem(mat,3,1),m_elem(mat,3,2),m_elem(mat,3,3))
+
+#define v_scan2(vec)(scanf("%lf %lf %lf",&v_x(*vec),&v_y(*vec),&v_w(*vec)))
+
+#define v_scan3(vec)(scanf("%lf %lf %lf %lf",&v_x(*vec),&v_y(*vec),\
+	&v_z(*vec),&v_w(*vec)))
+
+#ifdef __cplusplus
+
+int v_inters2 (const hvec2_t & p1,
+	       const hvec2_t & p2,
+	       const hvec2_t & q1,
+	       const hvec2_t & q2, hvec2_t * S1, hvec2_t * S2);
+
+extern "C"
+{
+#endif
+
+
+  void v_dupl2 (hvec2_t *, hvec2_t *);
+  void v_dupl3 (hvec3_t *, hvec3_t *);
+  void m_dupl2 (hmat2_t *, hmat2_t *);
+  void m_dupl3 (hmat3_t *, hmat3_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- clippoly-0.11.orig/graphmat++.3
+++ clippoly-0.11/graphmat++.3
@@ -1,47 +1,47 @@
-.TH GRAPHMAT++ 3 "20 October 1992"
-.SH NAME
--, +, len \- Syntatic simple interface to graphmat.
-.nf
-.SH SYNOPSIS
-.nf
-.B #include <graphmat++.h>
-.LP
-.B hvec2_t	operator-(const hvec2_t &)
-
-.B hvec2_t	operator-(const hvec2_t &, const hvec2_t &)
-
-.B hvec2_t	operator+(const hvec2_t &, const hvec2_t &)
-
-.B hvec2_t	operator*(const hmat2_t &, const hvec2_t &)
-
-.B hvec2_t	operator*(double, const hvec2_t &)
-
-.B hvec2_t	operator/(const hvec2_t &, double)
-
-.B const hvec2_t &operator+=(hvec2_t &, const hvec2_t &)
-
-.B const hvec2_t &operator-=(hvec2_t &, const hvec2_t &)
-
-.B const hvec2_t &operator*=(hvec2_t &, double)
-
-.B const hvec2_t &operator/=(hvec2_t &, double)
-
-.B double	len(const hvec2_t &)
-
-.SH DESCRIPTION
-These routines ar an addition to grapmat(3). 
-Actually, it are just some inline calls to the graphmat(3) equivalents.
-
-.SH SEE ALSO
-graphmat(3), graphadd(3), Graphics and matrix routines.
-
-.SH NOTE
-Only available in C++
-.br
-Code is in the C++ util files.
-
-A lot more should be implemented! (It's easy, any volunteers? :-)
-Also the hvec3_t and hmat* versions should exsist.
-
-.SH AUTHOR
-Klamer Schutte
+.TH GRAPHMAT++ 3 "20 October 1992"
+.SH NAME
+-, +, len \- Syntatic simple interface to graphmat.
+.nf
+.SH SYNOPSIS
+.nf
+.B #include <graphmat++.h>
+.LP
+.B hvec2_t	operator-(const hvec2_t &)
+
+.B hvec2_t	operator-(const hvec2_t &, const hvec2_t &)
+
+.B hvec2_t	operator+(const hvec2_t &, const hvec2_t &)
+
+.B hvec2_t	operator*(const hmat2_t &, const hvec2_t &)
+
+.B hvec2_t	operator*(double, const hvec2_t &)
+
+.B hvec2_t	operator/(const hvec2_t &, double)
+
+.B const hvec2_t &operator+=(hvec2_t &, const hvec2_t &)
+
+.B const hvec2_t &operator-=(hvec2_t &, const hvec2_t &)
+
+.B const hvec2_t &operator*=(hvec2_t &, double)
+
+.B const hvec2_t &operator/=(hvec2_t &, double)
+
+.B double	len(const hvec2_t &)
+
+.SH DESCRIPTION
+These routines ar an addition to grapmat(3). 
+Actually, it are just some inline calls to the graphmat(3) equivalents.
+
+.SH SEE ALSO
+graphmat(3), graphadd(3), Graphics and matrix routines.
+
+.SH NOTE
+Only available in C++
+.br
+Code is in the C++ util files.
+
+A lot more should be implemented! (It's easy, any volunteers? :-)
+Also the hvec3_t and hmat* versions should exsist.
+
+.SH AUTHOR
+Klamer Schutte
--- clippoly-0.11.orig/graphmat++.cc
+++ clippoly-0.11/graphmat++.cc
@@ -1,40 +1,34 @@
-static const char rcs_id[] = "$Header: /cvsroot/clippoly/clippoly/graphmat++.cc,v 1.5 2005/02/28 17:21:12 klamer Exp $";
-
-//    tutvis library
-
-//    Copyright (C) 1993  University of Twente
-
-//    klamer@mi.el.utwente.nl
-
-//    This library is free software; you can redistribute it and/or
-//    modify it under the terms of the GNU Library General Public
-//    License as published by the Free Software Foundation; either
-//    version 2 of the License, or (at your option) any later version.
-
-//    This library is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//    Library General Public License for more details.
-
-//    You should have received a copy of the GNU Library General Public
-//    License along with this library; if not, write to the Free
-//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-// $Log: graphmat++.cc,v $
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.1  1992/09/11  14:51:38  klamer
-// Initial revision
-//
-
-#ifdef __GNUG__
-#pragma implementation
-#pragma implementation "graphmat.h"
-#endif
-
-#include	"graphmat++.h"
-
-static const char h_rcs_id[] = GRAPHMATPLUSPLUS_H;
-
+//    tutvis library
+
+//    Copyright (C) 1993  University of Twente
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.1  1992/09/11  14:51:38  klamer
+// Initial revision
+//
+
+#ifdef __GNUG__
+#pragma implementation
+#pragma implementation "graphmat.h"
+#endif
+
+#include	"graphmat++.h"
--- clippoly-0.11.orig/graphmat++.h
+++ clippoly-0.11/graphmat++.h
@@ -1,232 +1,230 @@
-//    tutvis library
-
-//    Copyright (C) 1993  University of Twente
-
-//    klamer@mi.el.utwente.nl
-
-//    This library is free software; you can redistribute it and/or
-//    modify it under the terms of the GNU Library General Public
-//    License as published by the Free Software Foundation; either
-//    version 2 of the License, or (at your option) any later version.
-
-//    This library is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//    Library General Public License for more details.
-
-//    You should have received a copy of the GNU Library General Public
-//    License along with this library; if not, write to the Free
-//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-#ifndef GRAPHMATPLUSPLUS_H
-#define GRAPHMATPLUSPLUS_H	"$Header: /cvsroot/clippoly/clippoly/graphmat++.h,v 1.5 2005/02/28 17:21:12 klamer Exp $"
-
-// $Log: graphmat++.h,v $
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.5  1993/05/13  12:50:59  klamer
-// fixed v2 -= v2 to use vv_sub2 instead of vv_add2
-// added -v3, v3 * s, s * v3, v3 + v3, v3 -= v3
-//
-// Revision 1.4  1993/01/18  16:23:47  klamer
-// Added m3 * m3, m3 * v3 and v3 - v3.
-//
-// Revision 1.3  1992/10/20  11:02:52  klamer
-// Added operator versions of:
-// double * hvec2
-// hvec2 / double
-// hvec2 += hvec2
-// hvec2 -= hvec2
-// hvec2 *=double
-// hvec2 /= double
-//
-
-#ifndef GRAPHMAT_INCLUDE
-#include	<graphmat.h>
-#endif
-
-#ifdef __GNUG__
-#pragma	interface
-#endif
-
-inline hvec2_t
-operator-( const hvec2_t &h )
-{
-	hvec2_t	ret;
-
-	v_fill2(-v_x(h),-v_y(h),v_w(h), &ret);
-
-	return ret;
-}
-
-inline hvec2_t
-operator-( const hvec2_t &l,  const hvec2_t &r )
-{
-	hvec2_t	ret;
-
-	vv_sub2( &l, &r, &ret );
-
-	return ret;
-}
-
-inline hvec2_t
-operator+(  const hvec2_t &l,  const hvec2_t &r )
-{
-	hvec2_t	ret;
-
-	vv_add2( &l, &r, &ret );
-
-	return ret;
-}
-
-inline hvec2_t
-operator*( const hmat2_t &m, const hvec2_t &v )
-{
-	hvec2_t	ret;
-
-	mv_mul2( &m, &v, &ret );
-
-	return ret;
-}
-
-inline hvec2_t
-operator*( double s, const hvec2_t &v )
-{
-	hvec2_t	ret;
-
-	sv_mul2( s, &v, &ret );
-
-	return ret;
-}
-
-inline hvec2_t 
-operator/( const hvec2_t &v, double div )
-{
-	hvec2_t	ret;
-	
-	sv_mul2( 1.0/div, &v, &ret );
-
-	return ret;
-}
-
-inline hvec2_t const &
-operator+=( hvec2_t &v, const hvec2_t &add )
-{
-	vv_add2( &v, &add, &v );
-
-	return v;
-}
-
-inline hvec2_t const &
-operator-=( hvec2_t &v, const hvec2_t &sub )
-{
-	vv_sub2( &v, &sub, &v );
-
-	return v;
-}
-
-inline hvec2_t const &
-operator*=( hvec2_t &v, double mul )
-{
-	sv_mul2( mul, &v, &v );
-
-	return v;
-}
-
-inline hvec2_t const &
-operator/=( hvec2_t &v, double div )
-{
-	sv_mul2( 1.0/div, &v, &v );
-
-	return v;
-}
-
-inline double
-len(  const hvec2_t &v )
-{
-	return v_len2( &v );
-}
-
-inline hvec3_t
-operator-( const hvec3_t &h )
-{
-	hvec3_t	ret;
-
-	v_fill3(-v_x(h),-v_y(h), -v_z(h), v_w(h), &ret);
-
-	return ret;
-}
-
-inline hmat3_t
-operator*( const hmat3_t &l, const hmat3_t &r )
-{
-	hmat3_t	res;
-	
-	mm_mul3(&l, &r, &res);
-	
-	return res;
-}
-
-inline hvec3_t
-operator*( const hmat3_t &m, const hvec3_t &v )
-{
-	hvec3_t	res;
-	
-	mv_mul3(&m, &v, &res);
-	
-	return res;
-}
-
-inline hvec3_t
-operator-( const hvec3_t &l, const hvec3_t &r )
-{
-	hvec3_t	res;
-	
-	vv_sub3( &l, &r, &res );
-	
-	return res;
-}
-
-inline hvec3_t
-operator*( const hvec3_t &v, double s )
-{
-        hvec3_t ret;
-
-        sv_mul3( s, &v, &ret );
-
-        return ret;
-}
-
-
-inline hvec3_t
-operator*( double s, const hvec3_t &v )
-{
-        hvec3_t ret;
-
-        sv_mul3( s, &v, &ret );
-
-        return ret;
-}
-
-inline hvec3_t
-operator+(  const hvec3_t &l,  const hvec3_t &r )
-{
-	hvec3_t	ret;
-
-	vv_add3( &l, &r, &ret );
-
-	return ret;
-}
-
-inline hvec3_t const &
-operator-=( hvec3_t &v, const hvec3_t &sub )
-{
-	vv_sub3( &v, &sub, &v );
-
-	return v;
-}
-
-#endif
-
+//    tutvis library
+
+//    Copyright (C) 1993  University of Twente
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifndef GRAPHMATPLUSPLUS_H
+#define GRAPHMATPLUSPLUS_H
+
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.5  1993/05/13  12:50:59  klamer
+// fixed v2 -= v2 to use vv_sub2 instead of vv_add2
+// added -v3, v3 * s, s * v3, v3 + v3, v3 -= v3
+//
+// Revision 1.4  1993/01/18  16:23:47  klamer
+// Added m3 * m3, m3 * v3 and v3 - v3.
+//
+// Revision 1.3  1992/10/20  11:02:52  klamer
+// Added operator versions of:
+// double * hvec2
+// hvec2 / double
+// hvec2 += hvec2
+// hvec2 -= hvec2
+// hvec2 *=double
+// hvec2 /= double
+//
+
+#ifndef GRAPHMAT_INCLUDE
+#include	<graphmat.h>
+#endif
+
+#ifdef __GNUG__
+#pragma	interface
+#endif
+
+inline hvec2_t
+operator- (const hvec2_t & h)
+{
+  hvec2_t ret;
+
+  v_fill2 (-v_x (h), -v_y (h), v_w (h), &ret);
+
+  return ret;
+}
+
+inline hvec2_t
+operator- (const hvec2_t & l, const hvec2_t & r)
+{
+  hvec2_t ret;
+
+  vv_sub2 (&l, &r, &ret);
+
+  return ret;
+}
+
+inline hvec2_t
+operator+ (const hvec2_t & l, const hvec2_t & r)
+{
+  hvec2_t ret;
+
+  vv_add2 (&l, &r, &ret);
+
+  return ret;
+}
+
+inline hvec2_t
+operator* (const hmat2_t & m, const hvec2_t & v)
+{
+  hvec2_t ret;
+
+  mv_mul2 (&m, &v, &ret);
+
+  return ret;
+}
+
+inline hvec2_t
+operator* (double s, const hvec2_t & v)
+{
+  hvec2_t ret;
+
+  sv_mul2 (s, &v, &ret);
+
+  return ret;
+}
+
+inline hvec2_t
+operator/ (const hvec2_t & v, double div)
+{
+  hvec2_t ret;
+
+  sv_mul2 (1.0 / div, &v, &ret);
+
+  return ret;
+}
+
+inline hvec2_t const &
+operator+= (hvec2_t & v, const hvec2_t & add)
+{
+  vv_add2 (&v, &add, &v);
+
+  return v;
+}
+
+inline hvec2_t const &
+operator-= (hvec2_t & v, const hvec2_t & sub)
+{
+  vv_sub2 (&v, &sub, &v);
+
+  return v;
+}
+
+inline hvec2_t const &
+operator*= (hvec2_t & v, double mul)
+{
+  sv_mul2 (mul, &v, &v);
+
+  return v;
+}
+
+inline hvec2_t const &
+operator/= (hvec2_t & v, double div)
+{
+  sv_mul2 (1.0 / div, &v, &v);
+
+  return v;
+}
+
+inline double
+len (const hvec2_t & v)
+{
+  return v_len2 (&v);
+}
+
+inline hvec3_t
+operator- (const hvec3_t & h)
+{
+  hvec3_t ret;
+
+  v_fill3 (-v_x (h), -v_y (h), -v_z (h), v_w (h), &ret);
+
+  return ret;
+}
+
+inline hmat3_t
+operator* (const hmat3_t & l, const hmat3_t & r)
+{
+  hmat3_t res;
+
+  mm_mul3 (&l, &r, &res);
+
+  return res;
+}
+
+inline hvec3_t
+operator* (const hmat3_t & m, const hvec3_t & v)
+{
+  hvec3_t res;
+
+  mv_mul3 (&m, &v, &res);
+
+  return res;
+}
+
+inline hvec3_t
+operator- (const hvec3_t & l, const hvec3_t & r)
+{
+  hvec3_t res;
+
+  vv_sub3 (&l, &r, &res);
+
+  return res;
+}
+
+inline hvec3_t
+operator* (const hvec3_t & v, double s)
+{
+  hvec3_t ret;
+
+  sv_mul3 (s, &v, &ret);
+
+  return ret;
+}
+
+
+inline hvec3_t
+operator* (double s, const hvec3_t & v)
+{
+  hvec3_t ret;
+
+  sv_mul3 (s, &v, &ret);
+
+  return ret;
+}
+
+inline hvec3_t
+operator+ (const hvec3_t & l, const hvec3_t & r)
+{
+  hvec3_t ret;
+
+  vv_add3 (&l, &r, &ret);
+
+  return ret;
+}
+
+inline hvec3_t const &
+operator-= (hvec3_t & v, const hvec3_t & sub)
+{
+  vv_sub3 (&v, &sub, &v);
+
+  return v;
+}
+
+#endif
--- clippoly-0.11.orig/graphmat.3
+++ clippoly-0.11/graphmat.3
@@ -1,836 +1,836 @@
-.TH GRAPHMAT 3 "15 September 1992"
-.SH NAME
-m_alloc2, m_free2, v_alloc2, v_free2, m_alloc3, m_free3, v_alloc3, v_free3, m_cpy2, m_unity2, v_cpy2, v_fill2, v_unity2, v_zero2, m_cpy3, m_unity3, v_cpy3, v_fill3, v_unity3, v_zero3, m_det2, v_len2, vtmv_mul2, vv_inprod2, m_inv2, m_tra2, mm_add2, mm_mul2, mm_sub2, mtmm_mul2, sm_mul2, mv_mul2, sv_mul2, v_homo2, v_norm2, vv_add2, vv_sub2, vvt_mul2, m_det3, v_len3, vtmv_mul3, vv_inprod3, m_inv3, m_tra3, mm_add3, mm_mul3, mm_sub3, mtmm_mul3, sm_mul3, mv_mul3, sv_mul3, v_homo3, v_norm3, vv_add3, vv_cross3, vv_sub3, vvt_mul3, miraxis2, mirorig2, mirplane2, rot2, scaorig2, scaplane2, scaxis2, transl2, miraxis3, mirorig3, mirplane3, prjorthaxis, prjpersaxis, rot3, scaorig3, scaplane3, scaxis3, transl3 \- 3d graphics and associated matrix and vector routines
-.nf
-.SH SYNOPSIS
-.nf
-.B #include <graphmat.h>
-.LP
-.I /* Data initialisation */
-.LP
-.ta 1.0i
-.B hmat2_t 	*m_alloc2(m_result)
-.br
-.B hmat2_t 	*m_result;
-
-.B void		m_free2(matrix)
-.br
-.B hmat2_t	*matrix;
-
-.B hvec2_t  	*v_alloc2(v_result)
-.br
-.B hvec2_t 	*v_result;
-
-.B void		v_free2(vector)
-.br
-.B hmat2_t	*vector;
-
-.B hmat3_t 	*m_alloc3(m_result)
-.br
-.B hmat3_t 	*m_result;
-
-.B void		m_free3(matrix)
-.br
-.B hmat3_t	*matrix;
-
-.B hvec3_t 	*v_alloc3(v_result)
-.br
-.B hvec3_t 	*v_result;
-
-.B void		v_free3(vector)
-.br
-.B hmat3_t	*vector;
-
-.B hmat2_t 	*m_cpy2(m_source, m_result)
-.br
-.B hmat2_t 	*m_source, *m_result;
-
-.B hmat2_t 	*m_unity2( m_result)
-.br
-.B hmat2_t 	*m_result;
-
-.B hvec2_t 	*v_cpy2(v_source, v_result) 
-.br
-.B hvec2_t 	*v_source, *v_result;
-
-.B hvec2_t 	*v_fill2(x, y, w, v_result)
-.br
-.B double      	x, y, w;
-.br
-.B hvec2_t	*v_result;
-
-.B hvec2_t 	*v_unity2(axis, v_result)
-.br
-.B b_axis     	axis;
-.br
-.B hvec2_t 	*v_result;
-
-.B hvec2_t 	*v_zero2(v_result)
-.br
-.B hvec2_t 	*v_result;
-
-.B hmat3_t 	*m_cpy3(m_source, m_result)
-.br
-.B hmat3_t 	*m_source, *m_result;
-
-.B hmat3_t 	*m_unity3(m_result)
-.br
-.B hmat3_t 	*m_result;
-
-.B hvec3_t 	*v_cpy3(v_source, v_result) 
-.br
-.B hvec3_t 	*v_source, *v_result;
-
-.B hvec3_t 	*v_fill3(x, y, z, w, v_result)
-.br
-.B double     	x, y, z, w;
-.br
-.B hvec3_t	*v_result;
-
-.B hvec3_t 	*v_unity3(axis, v_result)
-.br
-.B b_axis     	axis;
-.br
-.B hvec3_t 	*v_result;
-
-.B hvec3_t 	*v_zero3(vector)
-.br
-.B hvec3_t 	*vector;
-
-.LP
-.I /* Basic Linear Algebra */
-.LP
-.B double    	m_det2(matrix)
-.br
-.B hmat2_t 	*matrix;
-
-.B double     	v_len2(vector)
-.br
-.B hvec2_t 	*vector;
-
-.B double     	vtmv_mul2(vector, matrix)
-.br
-.B hvec2_t 	*vector;
-.br
-.B hmat2_t 	*matrix;
-
-.B double     	vv_inprod2(vectorA, vectorB)
-.br
-.B hvec2_t 	*vectorA, *vectorB;
-
-.B hmat2_t 	*m_inv2(matrix, m_result)
-.br
-.B hmat2_t 	*matrix, *m_result;
-
-.B hmat2_t 	*m_tra2(matrix, m_result)
-.br
-.B hmat2_t 	*matrix, *m_result;
-
-.B hmat2_t 	*mm_add2(matrixA, matrixB, m_result)
-.br
-.B hmat2_t 	*matrixA, *matrixB, *m_result;
-
-.B hmat2_t 	*mm_mul2(matrixA, matrixB, m_result)
-.br
-.B hmat2_t 	*matrixA, *matrixB, *m_result;
-
-.B hmat2_t 	*mm_sub2(matrixA, matrixB, m_result)
-.br
-.B hmat2_t 	*matrixA, *matrixB, *m_result;
-
-.B hmat2_t 	*mtmm_mul2(matrixA, matrixB, m_result)
-.br
-.B hmat2_t 	*matrixA, *matrixB, *m_result;
-
-.B hmat2_t 	*sm_mul2(scalar, matrix, m_result)
-.br
-.B double     	scalar;
-.br
-.B hmat2_t 	*matrix, *m_result;
-
-.B hmat2_t	*vvt_mul2(vectorA, vectorB, m_result)
-.br
-.B hvec2_t	*vectorA, *vectorB;
-.br
-.B hmat2_t	*m_result;
-
-.B hvec2_t 	*mv_mul2(matrix, vector, v_result)
-.br
-.B hmat2      	*matrix;
-.br
-.B hvec2_t 	*vector, *v_result;
-
-.B hvec2_t 	*sv_mul2(scalar, vector, v_result)
-.br
-.B double    	scalar;
-.br
-.B hvec2_t  	*vector, *v_result;
-
-.B hvec2_t 	*v_homo2(vector, v_result)
-.br
-.B hvec2_t 	*vector, *v_result;
-
-.B hvec2_t 	*v_norm2(vector, v_result)
-.br
-.B hvec2_t 	*vector, *v_result;
-
-.B hvec2_t 	*vv_add2(vectorA, vectorB, v_result)
-.br
-.B hvec2_t 	*vectorA, *vectorB, *v_result;
-
-.B hvec2_t 	*vv_sub2(vectorA, vectorB, v_result)
-.br
-.B hvec2_t 	*vectorA, *vectorB, *v_result;
-
-.B double    	m_det3(matrix)
-.br
-.B hmat3_t 	*matrix;
-
-.B double 	v_len3(vector)
-.br
-.B hvec3_t 	*vector;
-
-.B double 	vtmv_mul3(vector, matrix)
-.br
-.B hvec3_t 	*vector;
-.br
-.B hmat3_t 	*matrix;
-
-.B double 	vv_inprod3(vectorA, vectorB)
-.br
-.B hvec3_t 	*vectorA, *vectorB;
-
-.B hmat3_t 	*m_inv3(matrix, m_result)
-.br
-.B hmat3_t 	*matrix, *m_result;
-
-.B hmat3_t 	*m_tra3(matrix, m_result)
-.br
-.B hmat3_t 	*matrix, *m_result;
-
-.B hmat3_t 	*mm_add3(matrixA, matrixB, m_result)
-.br
-.B hmat3_t 	*matrixA, *matrixB, *m_result;
-
-.B hmat3_t 	*mm_mul3(matrixA, matrixB, m_result)
-.br
-.B hmat3_t 	*matrixA, *matrixB, *m_result;
-
-.B hmat3_t 	*mm_sub3(matrixA, matrixB, m_result)
-.br
-.B hmat3_t 	*matrixA, *matrixB, *m_result;
-
-.B hmat3_t 	*mtmm_mul3(matrixA, matrixB, m_result)
-.br
-.B hmat3_t 	*matrixA, *matrixB, *m_result;
-
-.B hmat3_t 	*sm_mul3(scalar, matrix, m_result)
-.br
-.B double 	scalar;
-.br
-.B hmat3_t 	*matrix, *m_result;
-
-.B hmat3_t	*vvt_mul3(vectorA, vectorB, m_result)
-.br
-.B hvec3_t	*vectorA, *vectorB;
-.br
-.B hmat3_t	*m_result;
-
-.B hvec3_t 	*mv_mul3(matrix, vector, v_result)
-.br
-.B hmat3_t 	*matrix;
-.br
-.B *hvec3_t 	*vector, *v_result;
-
-.B hvec3_t 	*sv_mul3(scalar, vec, v_result)
-.br
-.B double 	scalar;
-.br
-.B hvec3_t  	*vector, *v_result;
-
-.B hvec3_t 	*v_homo3(vector, v_result)
-.br
-.B hvec3_t 	*vector, *v_result;
-
-.B hvec3_t 	*v_norm3(vector, v_result)
-.br
-.B hvec3_t 	*vector, *v_result;
-
-.B hvec3_t    	*vv_add3(vectorA, vectorB, v_result)
-.br
-.B hvec3_t    	*vectorA, *vectorB, *v_result;
-
-.B hvec3_t    	*vv_cross3(vectorA, vectorB, v_result)
-.br
-.B hvec3_t    	*vectorA, *vectorB, *v_result;
-
-.B hvec3_t    	*vv_sub3(vectorA, vectorB, v_result)
-.br
-.B hvec3_t    	*vectorA, *vectorB, *v_result;
-
-
-.LP
-.I /* Elementary transformations */
-.LP
-.B hmat2_t	*miraxis2(axis, m_result)
-.br
-.B b_axis	axis;
-.br
-.B hmat2_t	*m_result;
-
-.B hmat2_t	*mirorig2(m_result)
-.br
-.B hmat2_t	*m_result;
-
-.B hmat2_t	*rot2( rotation, m_result)
-.br
-.B double    	rotation;
-.br
-.B hmat2_t	*m_result;
-
-.B hmat2_t	*scaorig2(scale, m_result)
-.br
-.B double    	scale;
-.br
-.B hmat2_t	*m_result;
-
-.B hmat2_t	*scaxis2(scale, axis, m_result)
-.br
-.B double     	scale;
-.br
-.B b_axis	axis;
-.br
-.B hmat2_t	*m_result;
-
-.B hmat2_t	*transl2(translation, m_result)
-.br
-.B hvec2_t	*translation;
-.br
-.B hmat2_t	*m_result;
-
-.B hmat3_t	*miraxis3(axis, m_result)
-.br
-.B b_axis	axis;
-.br
-.B hmat3_t	*m_result;
-
-.B hmat3_t	*mirorig3(m_result)
-.br
-.B hmat3_t	*m_result;
-
-.B hmat3_t	*mirplane3(plane, m_result)
-.br
-.B b_axis	plane;
-.br
-.B hmat3_t	*m_result;
-
-.B hmat3_t	*prjorthaxis(axis, m_result)
-.br
-.B b_axis	axis;
-.br
-.B hmat3_t	*m_result;
-
-.B hmat3_t	*prjpersaxis(axis, m_result)
-.br
-.B b_axis	axis;
-.br
-.B hmat3_t	*m_result;
-
-.B hmat3_t	*rot3( rotation, axis, m_result)
-.br
-.B double    	rotation;
-.br
-.B b_axis	axis;
-.br
-.B hmat3_t	*m_result;
-
-.B hmat3_t	*scaorig3(scale, m_result)
-.br
-.B double    	scale;
-.br
-.B hmat3_t	*m_result;
-
-.B hmat3_t	*scaplane(scale, plane, m_result)
-.br
-.B double    	scale;
-.br
-.B b_axis	plane;
-.br
-.B hmat3_t	*m_result;
-
-.B hmat3_t	*scaxis3(scale, axis, m_result)
-.br
-.B double    	scale;
-.br
-.B b_axis	axis;
-.br
-.B hmat3_t	*m_result;
-
-.B hmat3_t	*transl3(translation, m_result)
-.br
-.B hvec3_t    	*translation;
-.br
-.B hmat3_t	*m_result;
-.SH DESCRIPTION
-Matrix and vector routines associated with 3d
-graphics in homogeneous coordinates, such as basic linear algebra
-and elementary transformations.
-.LP
-This library is setup with a multi-level approach.
-.br
-.I Level1 :
-.B the data level.
-.br
-.I Level 2:
-.B the data initialisation level.
-.br
-.I Level 3:
-.B basic linear algebra level.
-.br
-.I Level 4:
-.B elementary transformation level.
-.br
-
-.I
-Level 1,
-the data structures, is realised as follows :
-.br
-.B typedef union
-.br
-.B {
-.br
-.B	double a[3];
-.br
-.B	struct 
-.br
-.B	{
-.br
-.B		double    x, y, w;
-.br
-.B	} s;
-.br
-.B } hvec2_t;
-.LP
-.LP
-.B typedef union
-.br
-.B {
-.br
-.B	double a[4];
-.br
-.B	struct 
-.br
-.B	{
-.br
-.B		double    x, y, z, w;
-.br
-.B	} s;
-.br
-.B } hvec3_t;
-.LP
-.LP
-.B typedef struct
-.br
-.B { 
-.br
-.B	double m[3][3];
-.br
-.B } hmat2_t;
-.LP
-.LP
-.B typedef struct
-.br
-.B { 
-.br
-.B	double m[4][4];
-.br
-.B } hmat3_t;
-.LP
-.LP
-To access the data elements of a vector or a matrix can be accessed with the
-macros:
-.LP
-#define	v_x( vec )		((vec).s.x)
-.br
-#define	v_y( vec )		((vec).s.y)
-.br
-#define	v_z( vec )		((vec).s.z)
-.br
-#define	v_w( vec )		((vec).s.w)
-.br
-#define	v_elem( vec, i )	((vec).a[(i)])
-.br
-#define	m_elem( mat, i, j )	((mat).m[(i)][(j)])
-.br
-.LP
-.LP
-.B typedef enum
-.br
-.B {
-.br
-.B		X_AXIS, Y_AXIS, Z_AXIS
-.br
-.B } b_axis;
-.LP
-.LP 
-The functions are as follows sorted:
-.br
-first on the level in which they belong, then on their return value and then on their name.
-
-.SH NAMES
-
-The function names begin with an abbreviation of the type of
-operand, and in which order the operations will be carried out
-on that operand. Then the order of and which operation will be
-carried out, followed by the type of coordinates. (i.e
-.I vtmv_mul3(vector, matrix) :
-first take the transpose of 
-.I vector,
-multiply the transpose with  
-.I matrix,
-this result is multiplied by the incoming vector, all coordinates
-are homogeneous 3d coordinates.)
-
-.SH USAGE
-
-All the "functions" may have been implemented as macro's, so you can't
-take the address of a function. It is however guaranteed that arguments 
-of each function/macro will be evaluated only once, except for the result
-argument, which can be evaluated multiple times.
-.LP
-All operations can be used in place, but overlapping data gives
-unspecified results.
-.LP
-If the parameter 
-.I v_result
-or
-.I m_result
-of a function or the parameter of an initialisation function
-equals
-.B NULL,
-space for the parameter will be dynamically allocated using 
-.B malloc(),
-otherwise the parameter is assumed to hold a pointer to a memory
-area which can be used. A pointer to the used area (which may have been
-new allocated) is always returned.
-.br
-If an error occurred like memory could not be allocated,
-an attempt to divide by
-zero occurs, or an attempt to invert a singular matrix a general error-routine 
-will be called, which has
-two parameters :
-.I gm_errno
-and 
-.I gm_func.
-.br
-.I gm_errno
-is the error type which is one of the following
-constants : 
-.B DIV0,
-.B NOMEM
-or
-.B MATSING.
-.I gm_func
-is a pointer to a string which contains the name of
-the function where the error occurred.
-.LP
-A pointer to the error routine is defined as follows :
-.br
-.B void (* gm_error)(gm_errno, gm_func);
-.br
-.B gm_error_t gm_errno;
-.br
-.B char *gm_func;
-.LP
-With 
-.I gm_error_t 
-is defined as :
-.br
-.B typedef enum
-.br
-.B {
-.br
-.B	DIV0, NOMEM, MATSING
-.br
-.B } gm_error_t;
-.br
-.LP
-The default error handler will abort after printing a diagnostic. You can 
-redirect
-.I gm_error
-to your own error handler. It is not advisable to return from the error
-handler as error recovery is not expected to take place.
-.LP
-Matrices are of type 
-.B hmat3_t 
-or 
-.B hmat2_t 
-for 2d or 3d
-coordinates, respectively. 
-.br
-Vectors are of type 
-.B hvec3_t 
-or 
-.B hvec2_t.
-.LP
-The elements of a vector can be accessed in two manners, the
-first one is by name of an element of a structure, the second is
-like an array.
-.LP
-A plane is described by the normal to that plane, with the
-assumption made that the origin is an element of the plane. 
-.LP
-.I rotation 
-is assumed to be a radial.
-.LP
-If a function is deallocating memory, it will check if the
-incoming pointer is a
-.B NULL
-pointer.
-.LP
-.LP
-.I /* Level2 : Data initialisation */
-.LP
-.B m_alloc2(), v_alloc2(), m_alloc3(), v_alloc3() 
-allocate memory for a data item of type 
-.B hmat2_t, hvec2_t, hmat3_t
-and
-.B hvec3_t
-respectively.
-.br
-.B m_free2(), v_free2(), m_free3(), v_free3()
-reclaim the storage allocated previously. 
-.br
-.B m_cpy2(), m_cpy3()
-copies 
-.I m_matrix 
-into 
-.I m_result.
-.br
-.B m_unity2(), m_unity3()
-returns the unity matrix. (2d respectively 3d homogeneous coordinates)
-.br
-.B v_cpy2(), v_cpy3()
-copies 
-.I v_source
-into 
-.I v_result.
-(2d respectively 3d homogeneous coordinates)
-.br
-.B v_fill2(), v_fill3() 
-fills 
-.I v_result
-according the given values.
-.br
-.B v_unity2(), v_unity3()
-returns the unity vector with 
-.I w = 1.0,
-the incoming basic axis 
-.I axis = 1.0, 
-and the
-other element(s) are 0.0; (2d  respectively 3d homogeneous coordinates)
-.br
-.B v_zero2(), v_zero3() 
-return a vector with 
-.I w 
-= 1.0
-and the other elements 0.0;
-.br
-.B m_cpy2(), m_cpy3()
-copies 
-.I m_source
-into 
-.I m_result.
-(2d respectively 3d homogeneous coordinates)
-.LP
-.I /* level3 : Basic Linear Algebra */
-.LP
-.B m_det2(), m_det3()
-calculates the determinant of the incoming matrix. The determinant is
-calculated in cartesian rather than homogeneous coordinates.
-.br
-.B v_len2(), v_len3()
-calculates the length of the cathesian part of the homogeneous vector.
-.br
-.B vtmv_mul2(), vtmv_mul3()
-calculate the result of the transpose of the incoming vector
-multiplied by the incoming matrix multiplied by the incoming
-vector (2d respectively 3d homogeneous coordinates)
-.br
-.B vv_inprod2(), vv_inprod3() 
-calculates the geometrical innerproduct (vector . vector) of 
-.I vectorA
-and
-.I vectorB.
-.br
-.B m_inv2(), m_inv3()
-calculates the inverse of 
-.I matrix.
-It is an error if the matrix in singular.
-.br
-.B m_tra2(), m_tra3()
-calculates the transpose 
-.I matrix.
-(2d respectively 3d homogeneous coordinates)
-.br
-.B mm_add2(), mm_sub2(), mm_add3(), mm_sub3()
-calculates the result of 
-.I matrixA
-+ respectively -
-.I matrixB.
-This operation is unspecified in the sense of homogeneous coordinates; the
-matrices are taken in their normal, mathematial sense.
-.br
-.B mm_mul2(), mm_mul3()
-calculates the result of 
-.I matrixA*matrixB 
-(2d respectively 3d homogeneous coordinates)
-.br
-.B mtmm_mul2(), mtmm_mul3()
-calculates the result of the transpose of the incoming 
-.I matrixA
-multiplied by 
-.I matrixB 
-multiplied by 
-.I matrixA 
-(2d respectively 3d homogeneous coordinates)
-.br
-.B sm_mul2(), sm_mul3()
-calculates the result of 
-.I scalar*matrix 
-(2d respectively 3d homogeneous coordinates)
-.br
-.B mv_mul2(), mv_mul3()
-calculates the result of 
-.I matrix*vector
-(2d respectively 3d homogeneous coordinates)
-.br
-.B sv_mul2(), sv_mul3() 
-calculates the result of 
-.I scalar*vector. 
-(2d respectively 3d homogeneous coordinates)
-.br
-.B v_homo2(), v_homo3()
-homogenize 
-.I vector
-so that the 
-.I w
-component becomes 1.0 but the length of the vector in homogeneous coordinates
-stays the same. (2d respectively 3d homogeneous coordinates)
-.br
-.B v_norm2(), v_norm3()
-normalises the incoming vector so the length of the cartesian vector
-becomes 1.0. The homogeneous length stays the same.
-(2d respectively 3d homogeneous coordinates)
-.br
-.B vv_add2(), vv_sub2(), vv_add3(), vv_sub3()
-calculates the result of 
-.I vectorA
-+ respectively -
-.I vectorB.
-These operations are done in the mathematical sense. Be careful with homogeneous
-coordinates, as not every possible input makes sense.
-.br
-.B vvt_mul2(), vvt_mul3()
-calculates the result of 
-.I vectorA 
-multiplied by the transpose of
-.I vectorB 
-(2d respectively 3d homogeneous coordinates)
-.br
-.B vv_cross3()
-calculates the geometrical crossproduct (
-.I vectorA x vectorB) of two
-vectors (3d homogeneous coordinates)
-.LP
-.I /* level4 : Elementary transformations */
-.LP
-.B miraxis2(), miraxis3()
-calculates the mirror matrix with respect to 
-.I axis. 
-(2d respectively 3d homogeneous coordinates)
-.br
-.B mirorg2(), mirorg3()
-calculates the mirror matrix relative to the origin. (2d respectively 3d
-homogeneous coordinates)
-.br
-.B mirplane3()
-calculates the mirror matrix relative to a plane. (3d homogeneous
-coordinates)
-.br
-.B rot2()
-calculates the rotation matrix over 
-.I rotation
-relative to the origin.
-(2d homogeneous coordinates)
-.br
-.B rot3()
-calculates the rotation matrix over 
-.I rotation
-along 
-.I axis. 
-(3d homogeneous coordinates)
-.br
-.B scaorg2(), scaorg3()
-calculates the matrix of scaling with
-.I scale
-relative to the origin. (2d respectively 3d
-homogeneous coordinates)
-.br
-.B scaplane3()
-calculates the matrix of scaling with
-.I scale
-relative to a plane of which
-.I plane
-is the normal. (3d
-homogeneous coordinates)
-.br
-.B scaxis2(), scaxis3()
-calculates the matrix of scaling with
-.I scale
-relative to the line given by
-.I axis.
-(2d respectively 3d homogeneous coordinates)
-.br
-.B transl2(), transl3()
-calculates the translation matrix over 
-.I translation.
-(2d respectively 3d homogeneous coordinates)
-.br
-.B prjorthaxis()
-calculates the orthographic projection matrix along 
-.I axis.
-(3d homogeneous coordinates)
-.br
-.B prjpersaxis()
-calculates the perspective projection with along
-.I axis
-The focus is in the origin. The projection plane is on distance
-1.0 before the camera.
-(3d homogeneous coordinates)
-
-.SH CAVEATS
-Vector addition and subtraction and matrix addition and
-substraction are not defined for homogeneous coordinates.
-One can add and subtract a point vector and a free vector, but you have to normalise the point vector first.
-The result of the subtraction of two point vectors is a free vector.
-.LP
-Calculating the determinant of a matrix and the length of a vector is unspecified
-in the sense of homogeneous coordinates
-
-.SH RETURN VALUES
-There are six types of return values: 
-.B
-void, double, *hvec3_t, *hvec2_t, *hmat3_t and *hmat2_t.
-
-.SH SEE ALSO
-graphadd(3), graphmat++(3), fmatpinv(3TV), malloc(3V), Graphics and matrix routines.
-
-.SH NOTE
-Library file is
-.B /usr/local/lib/libgraphmat.a
-
-.SH AUTHOR
-Hans Gringhuis.
-.br
-Klamer Schutte
+.TH GRAPHMAT 3 "15 September 1992"
+.SH NAME
+m_alloc2, m_free2, v_alloc2, v_free2, m_alloc3, m_free3, v_alloc3, v_free3, m_cpy2, m_unity2, v_cpy2, v_fill2, v_unity2, v_zero2, m_cpy3, m_unity3, v_cpy3, v_fill3, v_unity3, v_zero3, m_det2, v_len2, vtmv_mul2, vv_inprod2, m_inv2, m_tra2, mm_add2, mm_mul2, mm_sub2, mtmm_mul2, sm_mul2, mv_mul2, sv_mul2, v_homo2, v_norm2, vv_add2, vv_sub2, vvt_mul2, m_det3, v_len3, vtmv_mul3, vv_inprod3, m_inv3, m_tra3, mm_add3, mm_mul3, mm_sub3, mtmm_mul3, sm_mul3, mv_mul3, sv_mul3, v_homo3, v_norm3, vv_add3, vv_cross3, vv_sub3, vvt_mul3, miraxis2, mirorig2, mirplane2, rot2, scaorig2, scaplane2, scaxis2, transl2, miraxis3, mirorig3, mirplane3, prjorthaxis, prjpersaxis, rot3, scaorig3, scaplane3, scaxis3, transl3 \- 3d graphics and associated matrix and vector routines
+.nf
+.SH SYNOPSIS
+.nf
+.B #include <graphmat.h>
+.LP
+.I /* Data initialisation */
+.LP
+.ta 1.0i
+.B hmat2_t 	*m_alloc2(m_result)
+.br
+.B hmat2_t 	*m_result;
+
+.B void		m_free2(matrix)
+.br
+.B hmat2_t	*matrix;
+
+.B hvec2_t  	*v_alloc2(v_result)
+.br
+.B hvec2_t 	*v_result;
+
+.B void		v_free2(vector)
+.br
+.B hmat2_t	*vector;
+
+.B hmat3_t 	*m_alloc3(m_result)
+.br
+.B hmat3_t 	*m_result;
+
+.B void		m_free3(matrix)
+.br
+.B hmat3_t	*matrix;
+
+.B hvec3_t 	*v_alloc3(v_result)
+.br
+.B hvec3_t 	*v_result;
+
+.B void		v_free3(vector)
+.br
+.B hmat3_t	*vector;
+
+.B hmat2_t 	*m_cpy2(m_source, m_result)
+.br
+.B hmat2_t 	*m_source, *m_result;
+
+.B hmat2_t 	*m_unity2( m_result)
+.br
+.B hmat2_t 	*m_result;
+
+.B hvec2_t 	*v_cpy2(v_source, v_result) 
+.br
+.B hvec2_t 	*v_source, *v_result;
+
+.B hvec2_t 	*v_fill2(x, y, w, v_result)
+.br
+.B double      	x, y, w;
+.br
+.B hvec2_t	*v_result;
+
+.B hvec2_t 	*v_unity2(axis, v_result)
+.br
+.B b_axis     	axis;
+.br
+.B hvec2_t 	*v_result;
+
+.B hvec2_t 	*v_zero2(v_result)
+.br
+.B hvec2_t 	*v_result;
+
+.B hmat3_t 	*m_cpy3(m_source, m_result)
+.br
+.B hmat3_t 	*m_source, *m_result;
+
+.B hmat3_t 	*m_unity3(m_result)
+.br
+.B hmat3_t 	*m_result;
+
+.B hvec3_t 	*v_cpy3(v_source, v_result) 
+.br
+.B hvec3_t 	*v_source, *v_result;
+
+.B hvec3_t 	*v_fill3(x, y, z, w, v_result)
+.br
+.B double     	x, y, z, w;
+.br
+.B hvec3_t	*v_result;
+
+.B hvec3_t 	*v_unity3(axis, v_result)
+.br
+.B b_axis     	axis;
+.br
+.B hvec3_t 	*v_result;
+
+.B hvec3_t 	*v_zero3(vector)
+.br
+.B hvec3_t 	*vector;
+
+.LP
+.I /* Basic Linear Algebra */
+.LP
+.B double    	m_det2(matrix)
+.br
+.B hmat2_t 	*matrix;
+
+.B double     	v_len2(vector)
+.br
+.B hvec2_t 	*vector;
+
+.B double     	vtmv_mul2(vector, matrix)
+.br
+.B hvec2_t 	*vector;
+.br
+.B hmat2_t 	*matrix;
+
+.B double     	vv_inprod2(vectorA, vectorB)
+.br
+.B hvec2_t 	*vectorA, *vectorB;
+
+.B hmat2_t 	*m_inv2(matrix, m_result)
+.br
+.B hmat2_t 	*matrix, *m_result;
+
+.B hmat2_t 	*m_tra2(matrix, m_result)
+.br
+.B hmat2_t 	*matrix, *m_result;
+
+.B hmat2_t 	*mm_add2(matrixA, matrixB, m_result)
+.br
+.B hmat2_t 	*matrixA, *matrixB, *m_result;
+
+.B hmat2_t 	*mm_mul2(matrixA, matrixB, m_result)
+.br
+.B hmat2_t 	*matrixA, *matrixB, *m_result;
+
+.B hmat2_t 	*mm_sub2(matrixA, matrixB, m_result)
+.br
+.B hmat2_t 	*matrixA, *matrixB, *m_result;
+
+.B hmat2_t 	*mtmm_mul2(matrixA, matrixB, m_result)
+.br
+.B hmat2_t 	*matrixA, *matrixB, *m_result;
+
+.B hmat2_t 	*sm_mul2(scalar, matrix, m_result)
+.br
+.B double     	scalar;
+.br
+.B hmat2_t 	*matrix, *m_result;
+
+.B hmat2_t	*vvt_mul2(vectorA, vectorB, m_result)
+.br
+.B hvec2_t	*vectorA, *vectorB;
+.br
+.B hmat2_t	*m_result;
+
+.B hvec2_t 	*mv_mul2(matrix, vector, v_result)
+.br
+.B hmat2      	*matrix;
+.br
+.B hvec2_t 	*vector, *v_result;
+
+.B hvec2_t 	*sv_mul2(scalar, vector, v_result)
+.br
+.B double    	scalar;
+.br
+.B hvec2_t  	*vector, *v_result;
+
+.B hvec2_t 	*v_homo2(vector, v_result)
+.br
+.B hvec2_t 	*vector, *v_result;
+
+.B hvec2_t 	*v_norm2(vector, v_result)
+.br
+.B hvec2_t 	*vector, *v_result;
+
+.B hvec2_t 	*vv_add2(vectorA, vectorB, v_result)
+.br
+.B hvec2_t 	*vectorA, *vectorB, *v_result;
+
+.B hvec2_t 	*vv_sub2(vectorA, vectorB, v_result)
+.br
+.B hvec2_t 	*vectorA, *vectorB, *v_result;
+
+.B double    	m_det3(matrix)
+.br
+.B hmat3_t 	*matrix;
+
+.B double 	v_len3(vector)
+.br
+.B hvec3_t 	*vector;
+
+.B double 	vtmv_mul3(vector, matrix)
+.br
+.B hvec3_t 	*vector;
+.br
+.B hmat3_t 	*matrix;
+
+.B double 	vv_inprod3(vectorA, vectorB)
+.br
+.B hvec3_t 	*vectorA, *vectorB;
+
+.B hmat3_t 	*m_inv3(matrix, m_result)
+.br
+.B hmat3_t 	*matrix, *m_result;
+
+.B hmat3_t 	*m_tra3(matrix, m_result)
+.br
+.B hmat3_t 	*matrix, *m_result;
+
+.B hmat3_t 	*mm_add3(matrixA, matrixB, m_result)
+.br
+.B hmat3_t 	*matrixA, *matrixB, *m_result;
+
+.B hmat3_t 	*mm_mul3(matrixA, matrixB, m_result)
+.br
+.B hmat3_t 	*matrixA, *matrixB, *m_result;
+
+.B hmat3_t 	*mm_sub3(matrixA, matrixB, m_result)
+.br
+.B hmat3_t 	*matrixA, *matrixB, *m_result;
+
+.B hmat3_t 	*mtmm_mul3(matrixA, matrixB, m_result)
+.br
+.B hmat3_t 	*matrixA, *matrixB, *m_result;
+
+.B hmat3_t 	*sm_mul3(scalar, matrix, m_result)
+.br
+.B double 	scalar;
+.br
+.B hmat3_t 	*matrix, *m_result;
+
+.B hmat3_t	*vvt_mul3(vectorA, vectorB, m_result)
+.br
+.B hvec3_t	*vectorA, *vectorB;
+.br
+.B hmat3_t	*m_result;
+
+.B hvec3_t 	*mv_mul3(matrix, vector, v_result)
+.br
+.B hmat3_t 	*matrix;
+.br
+.B *hvec3_t 	*vector, *v_result;
+
+.B hvec3_t 	*sv_mul3(scalar, vec, v_result)
+.br
+.B double 	scalar;
+.br
+.B hvec3_t  	*vector, *v_result;
+
+.B hvec3_t 	*v_homo3(vector, v_result)
+.br
+.B hvec3_t 	*vector, *v_result;
+
+.B hvec3_t 	*v_norm3(vector, v_result)
+.br
+.B hvec3_t 	*vector, *v_result;
+
+.B hvec3_t    	*vv_add3(vectorA, vectorB, v_result)
+.br
+.B hvec3_t    	*vectorA, *vectorB, *v_result;
+
+.B hvec3_t    	*vv_cross3(vectorA, vectorB, v_result)
+.br
+.B hvec3_t    	*vectorA, *vectorB, *v_result;
+
+.B hvec3_t    	*vv_sub3(vectorA, vectorB, v_result)
+.br
+.B hvec3_t    	*vectorA, *vectorB, *v_result;
+
+
+.LP
+.I /* Elementary transformations */
+.LP
+.B hmat2_t	*miraxis2(axis, m_result)
+.br
+.B b_axis	axis;
+.br
+.B hmat2_t	*m_result;
+
+.B hmat2_t	*mirorig2(m_result)
+.br
+.B hmat2_t	*m_result;
+
+.B hmat2_t	*rot2( rotation, m_result)
+.br
+.B double    	rotation;
+.br
+.B hmat2_t	*m_result;
+
+.B hmat2_t	*scaorig2(scale, m_result)
+.br
+.B double    	scale;
+.br
+.B hmat2_t	*m_result;
+
+.B hmat2_t	*scaxis2(scale, axis, m_result)
+.br
+.B double     	scale;
+.br
+.B b_axis	axis;
+.br
+.B hmat2_t	*m_result;
+
+.B hmat2_t	*transl2(translation, m_result)
+.br
+.B hvec2_t	*translation;
+.br
+.B hmat2_t	*m_result;
+
+.B hmat3_t	*miraxis3(axis, m_result)
+.br
+.B b_axis	axis;
+.br
+.B hmat3_t	*m_result;
+
+.B hmat3_t	*mirorig3(m_result)
+.br
+.B hmat3_t	*m_result;
+
+.B hmat3_t	*mirplane3(plane, m_result)
+.br
+.B b_axis	plane;
+.br
+.B hmat3_t	*m_result;
+
+.B hmat3_t	*prjorthaxis(axis, m_result)
+.br
+.B b_axis	axis;
+.br
+.B hmat3_t	*m_result;
+
+.B hmat3_t	*prjpersaxis(axis, m_result)
+.br
+.B b_axis	axis;
+.br
+.B hmat3_t	*m_result;
+
+.B hmat3_t	*rot3( rotation, axis, m_result)
+.br
+.B double    	rotation;
+.br
+.B b_axis	axis;
+.br
+.B hmat3_t	*m_result;
+
+.B hmat3_t	*scaorig3(scale, m_result)
+.br
+.B double    	scale;
+.br
+.B hmat3_t	*m_result;
+
+.B hmat3_t	*scaplane(scale, plane, m_result)
+.br
+.B double    	scale;
+.br
+.B b_axis	plane;
+.br
+.B hmat3_t	*m_result;
+
+.B hmat3_t	*scaxis3(scale, axis, m_result)
+.br
+.B double    	scale;
+.br
+.B b_axis	axis;
+.br
+.B hmat3_t	*m_result;
+
+.B hmat3_t	*transl3(translation, m_result)
+.br
+.B hvec3_t    	*translation;
+.br
+.B hmat3_t	*m_result;
+.SH DESCRIPTION
+Matrix and vector routines associated with 3d
+graphics in homogeneous coordinates, such as basic linear algebra
+and elementary transformations.
+.LP
+This library is setup with a multi-level approach.
+.br
+.I Level1 :
+.B the data level.
+.br
+.I Level 2:
+.B the data initialisation level.
+.br
+.I Level 3:
+.B basic linear algebra level.
+.br
+.I Level 4:
+.B elementary transformation level.
+.br
+
+.I
+Level 1,
+the data structures, is realised as follows :
+.br
+.B typedef union
+.br
+.B {
+.br
+.B	double a[3];
+.br
+.B	struct 
+.br
+.B	{
+.br
+.B		double    x, y, w;
+.br
+.B	} s;
+.br
+.B } hvec2_t;
+.LP
+.LP
+.B typedef union
+.br
+.B {
+.br
+.B	double a[4];
+.br
+.B	struct 
+.br
+.B	{
+.br
+.B		double    x, y, z, w;
+.br
+.B	} s;
+.br
+.B } hvec3_t;
+.LP
+.LP
+.B typedef struct
+.br
+.B { 
+.br
+.B	double m[3][3];
+.br
+.B } hmat2_t;
+.LP
+.LP
+.B typedef struct
+.br
+.B { 
+.br
+.B	double m[4][4];
+.br
+.B } hmat3_t;
+.LP
+.LP
+To access the data elements of a vector or a matrix can be accessed with the
+macros:
+.LP
+#define	v_x( vec )		((vec).s.x)
+.br
+#define	v_y( vec )		((vec).s.y)
+.br
+#define	v_z( vec )		((vec).s.z)
+.br
+#define	v_w( vec )		((vec).s.w)
+.br
+#define	v_elem( vec, i )	((vec).a[(i)])
+.br
+#define	m_elem( mat, i, j )	((mat).m[(i)][(j)])
+.br
+.LP
+.LP
+.B typedef enum
+.br
+.B {
+.br
+.B		X_AXIS, Y_AXIS, Z_AXIS
+.br
+.B } b_axis;
+.LP
+.LP 
+The functions are as follows sorted:
+.br
+first on the level in which they belong, then on their return value and then on their name.
+
+.SH NAMES
+
+The function names begin with an abbreviation of the type of
+operand, and in which order the operations will be carried out
+on that operand. Then the order of and which operation will be
+carried out, followed by the type of coordinates. (i.e
+.I vtmv_mul3(vector, matrix) :
+first take the transpose of 
+.I vector,
+multiply the transpose with  
+.I matrix,
+this result is multiplied by the incoming vector, all coordinates
+are homogeneous 3d coordinates.)
+
+.SH USAGE
+
+All the "functions" may have been implemented as macro's, so you can't
+take the address of a function. It is however guaranteed that arguments 
+of each function/macro will be evaluated only once, except for the result
+argument, which can be evaluated multiple times.
+.LP
+All operations can be used in place, but overlapping data gives
+unspecified results.
+.LP
+If the parameter 
+.I v_result
+or
+.I m_result
+of a function or the parameter of an initialisation function
+equals
+.B NULL,
+space for the parameter will be dynamically allocated using 
+.B malloc(),
+otherwise the parameter is assumed to hold a pointer to a memory
+area which can be used. A pointer to the used area (which may have been
+new allocated) is always returned.
+.br
+If an error occurred like memory could not be allocated,
+an attempt to divide by
+zero occurs, or an attempt to invert a singular matrix a general error-routine 
+will be called, which has
+two parameters :
+.I gm_errno
+and 
+.I gm_func.
+.br
+.I gm_errno
+is the error type which is one of the following
+constants : 
+.B DIV0,
+.B NOMEM
+or
+.B MATSING.
+.I gm_func
+is a pointer to a string which contains the name of
+the function where the error occurred.
+.LP
+A pointer to the error routine is defined as follows :
+.br
+.B void (* gm_error)(gm_errno, gm_func);
+.br
+.B gm_error_t gm_errno;
+.br
+.B char *gm_func;
+.LP
+With 
+.I gm_error_t 
+is defined as :
+.br
+.B typedef enum
+.br
+.B {
+.br
+.B	DIV0, NOMEM, MATSING
+.br
+.B } gm_error_t;
+.br
+.LP
+The default error handler will abort after printing a diagnostic. You can 
+redirect
+.I gm_error
+to your own error handler. It is not advisable to return from the error
+handler as error recovery is not expected to take place.
+.LP
+Matrices are of type 
+.B hmat3_t 
+or 
+.B hmat2_t 
+for 2d or 3d
+coordinates, respectively. 
+.br
+Vectors are of type 
+.B hvec3_t 
+or 
+.B hvec2_t.
+.LP
+The elements of a vector can be accessed in two manners, the
+first one is by name of an element of a structure, the second is
+like an array.
+.LP
+A plane is described by the normal to that plane, with the
+assumption made that the origin is an element of the plane. 
+.LP
+.I rotation 
+is assumed to be a radial.
+.LP
+If a function is deallocating memory, it will check if the
+incoming pointer is a
+.B NULL
+pointer.
+.LP
+.LP
+.I /* Level2 : Data initialisation */
+.LP
+.B m_alloc2(), v_alloc2(), m_alloc3(), v_alloc3() 
+allocate memory for a data item of type 
+.B hmat2_t, hvec2_t, hmat3_t
+and
+.B hvec3_t
+respectively.
+.br
+.B m_free2(), v_free2(), m_free3(), v_free3()
+reclaim the storage allocated previously. 
+.br
+.B m_cpy2(), m_cpy3()
+copies 
+.I m_matrix 
+into 
+.I m_result.
+.br
+.B m_unity2(), m_unity3()
+returns the unity matrix. (2d respectively 3d homogeneous coordinates)
+.br
+.B v_cpy2(), v_cpy3()
+copies 
+.I v_source
+into 
+.I v_result.
+(2d respectively 3d homogeneous coordinates)
+.br
+.B v_fill2(), v_fill3() 
+fills 
+.I v_result
+according the given values.
+.br
+.B v_unity2(), v_unity3()
+returns the unity vector with 
+.I w = 1.0,
+the incoming basic axis 
+.I axis = 1.0, 
+and the
+other element(s) are 0.0; (2d  respectively 3d homogeneous coordinates)
+.br
+.B v_zero2(), v_zero3() 
+return a vector with 
+.I w 
+= 1.0
+and the other elements 0.0;
+.br
+.B m_cpy2(), m_cpy3()
+copies 
+.I m_source
+into 
+.I m_result.
+(2d respectively 3d homogeneous coordinates)
+.LP
+.I /* level3 : Basic Linear Algebra */
+.LP
+.B m_det2(), m_det3()
+calculates the determinant of the incoming matrix. The determinant is
+calculated in cartesian rather than homogeneous coordinates.
+.br
+.B v_len2(), v_len3()
+calculates the length of the cathesian part of the homogeneous vector.
+.br
+.B vtmv_mul2(), vtmv_mul3()
+calculate the result of the transpose of the incoming vector
+multiplied by the incoming matrix multiplied by the incoming
+vector (2d respectively 3d homogeneous coordinates)
+.br
+.B vv_inprod2(), vv_inprod3() 
+calculates the geometrical innerproduct (vector . vector) of 
+.I vectorA
+and
+.I vectorB.
+.br
+.B m_inv2(), m_inv3()
+calculates the inverse of 
+.I matrix.
+It is an error if the matrix in singular.
+.br
+.B m_tra2(), m_tra3()
+calculates the transpose 
+.I matrix.
+(2d respectively 3d homogeneous coordinates)
+.br
+.B mm_add2(), mm_sub2(), mm_add3(), mm_sub3()
+calculates the result of 
+.I matrixA
++ respectively -
+.I matrixB.
+This operation is unspecified in the sense of homogeneous coordinates; the
+matrices are taken in their normal, mathematial sense.
+.br
+.B mm_mul2(), mm_mul3()
+calculates the result of 
+.I matrixA*matrixB 
+(2d respectively 3d homogeneous coordinates)
+.br
+.B mtmm_mul2(), mtmm_mul3()
+calculates the result of the transpose of the incoming 
+.I matrixA
+multiplied by 
+.I matrixB 
+multiplied by 
+.I matrixA 
+(2d respectively 3d homogeneous coordinates)
+.br
+.B sm_mul2(), sm_mul3()
+calculates the result of 
+.I scalar*matrix 
+(2d respectively 3d homogeneous coordinates)
+.br
+.B mv_mul2(), mv_mul3()
+calculates the result of 
+.I matrix*vector
+(2d respectively 3d homogeneous coordinates)
+.br
+.B sv_mul2(), sv_mul3() 
+calculates the result of 
+.I scalar*vector. 
+(2d respectively 3d homogeneous coordinates)
+.br
+.B v_homo2(), v_homo3()
+homogenize 
+.I vector
+so that the 
+.I w
+component becomes 1.0 but the length of the vector in homogeneous coordinates
+stays the same. (2d respectively 3d homogeneous coordinates)
+.br
+.B v_norm2(), v_norm3()
+normalises the incoming vector so the length of the cartesian vector
+becomes 1.0. The homogeneous length stays the same.
+(2d respectively 3d homogeneous coordinates)
+.br
+.B vv_add2(), vv_sub2(), vv_add3(), vv_sub3()
+calculates the result of 
+.I vectorA
++ respectively -
+.I vectorB.
+These operations are done in the mathematical sense. Be careful with homogeneous
+coordinates, as not every possible input makes sense.
+.br
+.B vvt_mul2(), vvt_mul3()
+calculates the result of 
+.I vectorA 
+multiplied by the transpose of
+.I vectorB 
+(2d respectively 3d homogeneous coordinates)
+.br
+.B vv_cross3()
+calculates the geometrical crossproduct (
+.I vectorA x vectorB) of two
+vectors (3d homogeneous coordinates)
+.LP
+.I /* level4 : Elementary transformations */
+.LP
+.B miraxis2(), miraxis3()
+calculates the mirror matrix with respect to 
+.I axis. 
+(2d respectively 3d homogeneous coordinates)
+.br
+.B mirorg2(), mirorg3()
+calculates the mirror matrix relative to the origin. (2d respectively 3d
+homogeneous coordinates)
+.br
+.B mirplane3()
+calculates the mirror matrix relative to a plane. (3d homogeneous
+coordinates)
+.br
+.B rot2()
+calculates the rotation matrix over 
+.I rotation
+relative to the origin.
+(2d homogeneous coordinates)
+.br
+.B rot3()
+calculates the rotation matrix over 
+.I rotation
+along 
+.I axis. 
+(3d homogeneous coordinates)
+.br
+.B scaorg2(), scaorg3()
+calculates the matrix of scaling with
+.I scale
+relative to the origin. (2d respectively 3d
+homogeneous coordinates)
+.br
+.B scaplane3()
+calculates the matrix of scaling with
+.I scale
+relative to a plane of which
+.I plane
+is the normal. (3d
+homogeneous coordinates)
+.br
+.B scaxis2(), scaxis3()
+calculates the matrix of scaling with
+.I scale
+relative to the line given by
+.I axis.
+(2d respectively 3d homogeneous coordinates)
+.br
+.B transl2(), transl3()
+calculates the translation matrix over 
+.I translation.
+(2d respectively 3d homogeneous coordinates)
+.br
+.B prjorthaxis()
+calculates the orthographic projection matrix along 
+.I axis.
+(3d homogeneous coordinates)
+.br
+.B prjpersaxis()
+calculates the perspective projection with along
+.I axis
+The focus is in the origin. The projection plane is on distance
+1.0 before the camera.
+(3d homogeneous coordinates)
+
+.SH CAVEATS
+Vector addition and subtraction and matrix addition and
+subtraction are not defined for homogeneous coordinates.
+One can add and subtract a point vector and a free vector, but you have to normalise the point vector first.
+The result of the subtraction of two point vectors is a free vector.
+.LP
+Calculating the determinant of a matrix and the length of a vector is unspecified
+in the sense of homogeneous coordinates
+
+.SH RETURN VALUES
+There are six types of return values: 
+.B
+void, double, *hvec3_t, *hvec2_t, *hmat3_t and *hmat2_t.
+
+.SH SEE ALSO
+graphadd(3), graphmat++(3), fmatpinv(3TV), malloc(3V), Graphics and matrix routines.
+
+.SH NOTE
+Library file is
+.B /usr/local/lib/libgraphmat.a
+
+.SH AUTHOR
+Hans Gringhuis.
+.br
+Klamer Schutte
--- clippoly-0.11.orig/graphmat.c
+++ clippoly-0.11/graphmat.c
@@ -1,1665 +1,1702 @@
-static char rcs_id[] = "$Header: /cvsroot/clippoly/clippoly/graphmat.c,v 1.5 2005/02/28 17:21:12 klamer Exp $";
-/*
-  $Log: graphmat.c,v $
-  Revision 1.5  2005/02/28 17:21:12  klamer
-  Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-  Change use of (libg++) String to ANSI C++ string.
-
- * Revision 1.8  1993/01/28  15:25:47  klamer
- * Changed scaxis: now is scaled along the axis; the line-mirror behaviour
- * is now deleted.
- *
- * Revision 1.7  1993/01/18  16:28:54  klamer
- * added inclusion of err.h.
- * Added return value to mm_add3
- * Simplified v_norm3
- * Changed prjorthaxis3. Tricky -- check for results.
- * Deleted unused variables in prjpersaxis.
- *
- * Revision 1.6  1992/03/26  16:33:05  klamer
- * prjpersaxis corrected for Z_AXIS (implemented proper).
- *
- * Revision 1.5  1992/03/25  15:13:41  klamer
- * made lint complain less.
- *
- * Revision 1.4  1992/01/29  16:19:41  aartjan
- * bugs in rot3() and vv_inprod3() fixed
- *
- * Revision 1.3  1992/01/29  08:45:21  aartjan
- * sv_mul bug fixed; vv_inprod optimized
- *
-
-  graphmat.c - 3d graphics and associated matrix and vector
-               routines in homogeneous coordinates.
-   Author : Hans Gringhuis
-*/
-
-#include	<err.h>
-
-#include <graphmat.h>
-
-static int   default_gm_error();
-/***** initialisation of general error-routine ******/
-int (*gm_error)() = default_gm_error;
-
-
-/****** General error-routine ******/
-static int
-default_gm_error(gm_errno, gm_func)
-gm_error_t  gm_errno;
-char   *gm_func;
-{
-  switch(gm_errno)
-  {
-     case NOMEM : fatal("Graphmat-error : Memory allocation failure in function : %s\n", gm_func);
-     case DIV0 : fatal("Graphmat-error : Division by zero in function : %s\n", gm_func);
-     case MATSING : fatal("Graphmat-error : Matrix is singular in function : %s\n", gm_func);
-     default : fatal("Graphmat-error : Undefined error in function : %s\n", gm_func);
-  };
-}
-
-/****** Level 2 : Data initialisation ******/
-hmat2_t *
-m_cpy2(m_source, m_result)
-const hmat2_t *m_source;
-hmat2_t *m_result;
-{
-   
-   m_result = gm_ALLOC(hmat2_t, m_result, "m_cpy2()");
-
-   *m_result = *m_source;
-
-   return m_result;
-}
-
-
-hmat2_t *
-m_unity2(m_result)
-hmat2_t *m_result;
-{
-   int i, j;
-
-   m_result = gm_ALLOC(hmat2_t, m_result, "m_unity2()");
-
-   for(i=0; i<3; i++)
-     for(j=0; j<3; j++)
-       m_elem(*m_result, i, j) = (i != j) ? 0.0 : 1.0;
-
-   return m_result;
-}
-
-
-hvec2_t *
-v_cpy2(v_source, v_result)
-const hvec2_t *v_source;
-hvec2_t *v_result;
-{
-   v_result = gm_ALLOC(hvec2_t, v_result, "v_cpy2");
-
-   *v_result = *v_source;
-
-   return v_result;
-}
-
-
-hvec2_t *
-v_fill2(x, y, w, v_result)
-double  x, y, w;
-hvec2_t *v_result;
-{
-   v_result = gm_ALLOC(hvec2_t, v_result, "v_fill2()");
-
-   v_x(*v_result) = x;
-   v_y(*v_result) = y;
-   v_w(*v_result) = w;
-
-   return v_result;
-}
-
-
-hvec2_t *
-v_unity2(axis, v_result)
-b_axis  axis;
-hvec2_t *v_result;
-{
-   v_result = gm_ALLOC(hvec2_t, v_result, "v_unity2()");
-
-   if(axis == X_AXIS)
-   {
-     v_x(*v_result) = 1.0;
-     v_y(*v_result) = 0.0;
-   }
-   else
-   {
-     v_x(*v_result) = 0.0;
-     v_y(*v_result) = 1.0;
-   };
-   v_w(*v_result) = 1.0;
-
-   return v_result;
-}
-
-hvec2_t *
-v_zero2(v_result)
-hvec2_t *v_result;
-{
-   v_result = gm_ALLOC(hvec2_t, v_result, "v_zero2()");
-
-   v_x(*v_result) = v_y(*v_result) = 0.0;
-   v_w(*v_result) = 1.0;
-
-   return v_result;
-}
-
-
-hmat3_t *
-m_cpy3(m_source, m_result)
-const hmat3_t *m_source;
-hmat3_t *m_result;
-{
-   m_result = gm_ALLOC(hmat3_t, m_result, "m_cpy3()");
-
-   *m_result = *m_source;
-
-   return m_result;
-}
-
-
-hmat3_t *
-m_unity3(m_result)
-hmat3_t *m_result;
-{
-   int i, j;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "m_unity3()");
-
-   for(i=0; i<4; i++)
-     for(j=0; j<4; j++)
-          m_elem(*m_result, i, j) = (i != j) ? 0.0 :
-1.0;
-
-   return m_result;
-}
-
-
-hvec3_t *
-v_cpy3(v_source, v_result)
-const hvec3_t *v_source;
-hvec3_t *v_result;
-{
-   v_result = gm_ALLOC(hvec3_t, v_result, "v_cpy3()");
-
-   *v_result = *v_source;
-
-   return v_result;
-}
-
-
-hvec3_t *
-v_fill3(x, y, z, w, v_result)
-double  x, y, z, w;
-hvec3_t *v_result;
-{
-   v_result = gm_ALLOC(hvec3_t, v_result, "v_fill3()");
-
-   v_x(*v_result) = x;
-   v_y(*v_result) = y;
-   v_z(*v_result) = z;
-   v_w(*v_result) = w;
-
-   return v_result;
-}
-
-
-hvec3_t *
-v_unity3(axis, v_result)
-b_axis  axis;
-hvec3_t *v_result;
-{
-   v_result = gm_ALLOC(hvec3_t, v_result, "v_unity3()");
-
-   switch(axis)
-   {
-     case X_AXIS : v_x(*v_result) = 1.0;
-                   v_y(*v_result) = v_z(*v_result) = 0.0;
-                   break;
-     case Y_AXIS : v_y(*v_result) = 1.0;
-                   v_x(*v_result) = v_z(*v_result) = 0.0;
-                   break;
-     default : v_z(*v_result) = 1.0;
-               v_x(*v_result) = v_y(*v_result) = 0.0;
-               break;
-   };
-   v_w(*v_result) = 1.0;
-
-   return v_result;
-}
-
-hvec3_t *
-v_zero3(v_result)
-hvec3_t *v_result;
-{
-   v_result = gm_ALLOC(hvec3_t, v_result, "v_zero3()");
-
-   v_x(*v_result) = v_y(*v_result) = v_z(*v_result) = 0.0;
-   v_w(*v_result) = 1.0;
-
-   return v_result;
-}
-
-
-/****** Level 3 : Basic lineair algebra : 2D homogeneous coordinates ******/
-double
-m_det2(matrix)
-const hmat2_t *matrix;
-{
-
-   return
-	m_elem(*matrix,0,0) * (m_elem(*matrix,1,1) *
-	m_elem(*matrix,2,2) -
-	m_elem(*matrix,1,2) * m_elem(*matrix,2,1)) -
-	m_elem(*matrix,1,0) * (m_elem(*matrix,0,1) *
-	m_elem(*matrix,2,2) -
-	m_elem(*matrix,0,2) * m_elem(*matrix,2,1)) +
-	m_elem(*matrix,2,0) * (m_elem(*matrix,0,1) *
-	m_elem(*matrix,1,2) -
-	m_elem(*matrix,0,2) * m_elem(*matrix,1,1));
-
-}
-
-double
-v_len2(vector)
-const hvec2_t *vector;
-{
-   double  result;
-
-   result = ((sqrt(v_x(*vector) * v_x(*vector) + 
-              v_y(*vector) * v_y(*vector))));
-
-   return v_w(*vector) != 0.0 ? result / v_w(*vector) : result;
-}
-
-
-double
-vtmv_mul2(vector, matrix)
-const hvec2_t *vector;
-const hmat2_t *matrix;
-{
-
-   return
-     ((v_x(*vector) * m_elem(*matrix, 0, 0) +
-      v_y(*vector) * m_elem(*matrix, 1, 0) +
-      v_w(*vector) * m_elem(*matrix, 2, 0)) * 
-      v_x(*vector)) +
-      ((v_x(*vector) * m_elem(*matrix, 0, 1) +
-      v_y(*vector) * m_elem(*matrix, 1, 1) +
-      v_w(*vector) * m_elem(*matrix, 2, 1)) *
-      v_y(*vector)) +
-      ((v_x(*vector) * m_elem(*matrix, 0, 2) +
-      v_y(*vector) * m_elem(*matrix, 1, 2) +
-      v_w(*vector) * m_elem(*matrix, 2, 2)) *
-      v_w(*vector));
-}
-
-
-
-double
-vv_inprod2(vectorA, vectorB)
-const hvec2_t *vectorA;
-const hvec2_t *vectorB;
-{  double  result, div;
-
-   result = v_x(*vectorA) * v_x(*vectorB) + 
-            v_y(*vectorA) * v_y(*vectorB); 
-   div = 1.0;
-   if(v_w(*vectorA) != 0.0 && v_w(*vectorA) != 1.0)
-     div *= v_w(*vectorA);
-   if(v_w(*vectorB) != 0.0 && v_w(*vectorB) != 1.0)
-     div *= v_w(*vectorB);
-   if(div!=1.0) return result/div;
-
-   return result;
-}
-
-/* Used by "m_inv2()" */
-static void 
-submultiples2(m_input, m_result, rownr, workingrow)
-hmat2_t *m_input, *m_result;
-int  rownr, workingrow;
-{
-   int i;
-   double  subtractionfactor;
-   
-   if((subtractionfactor = m_elem(*m_input, workingrow, rownr))
-!= 0.0)
-   {
-     for(i=rownr; i<3; i++)
-        m_elem(*m_input,workingrow,i) -= m_elem(*m_input,rownr,i) * subtractionfactor;
-
-     for(i=0; i<3; i++)
-        m_elem(*m_result,workingrow,i) -= m_elem(*m_result,rownr,i) * subtractionfactor;
-   };
-} 
-
-/* Used by "m_inv2()" */
-static  void
-interchangerow2(m_input, m_result, rownr)
-hmat2_t *m_input, *m_result;
-int rownr;
-{
-   int nextelement = rownr+1, i;
-   double  buffer;
-
-   while(m_elem(*m_input, nextelement, rownr) == 0.0) 
-     if(++nextelement == 3)
-        gm_error(MATSING, "m_inv2()");
-
-   /* interchange one rowelement with an element of */
-   /* a row with a nonzeroentry in the same column */
-   for(i=0; i<3; i++)
-   {
-     buffer = m_elem(*m_input, nextelement, i);
-     m_elem(*m_input, nextelement, i) = m_elem(*m_input, rownr, i);
-     m_elem(*m_input, rownr, i) = buffer;
-     
-     buffer = m_elem(*m_result, nextelement, i);
-     m_elem(*m_result, nextelement, i) = m_elem(*m_result, rownr, i);
-     m_elem(*m_result, rownr, i) = buffer;
-   };
-}
-
-/* Used by m_inv2()" */
-static  void
-reduce_row2(m_input, m_result, rownr)
-hmat2_t *m_input, *m_result;
-int rownr;
-{
-   int i;
-   double  factor;
-
-   if(m_elem(*m_input, rownr, rownr) == 0.0)
-     /* interchange this row with another row to  
-       bring a nonzero entry in the main diagonal */
-     interchangerow2(m_input, m_result, rownr);
-
-   /* introduce a leading one by dividing the whole row */
-   factor = m_elem(*m_input, rownr, rownr);
-   for(i=rownr; i<3; i++)
-     m_elem(*m_input, rownr, i) /= factor;
-   for(i=0; i<3; i++)
-     m_elem(*m_result, rownr, i) /= factor;
-     
-
-   for(i=0; i<3; i++)
-        if(i != rownr)
-     /* subtract suitable multiples of this row to the other rows */
-     /* so that all other entries in this column become zeros.  */
-        submultiples2(m_input, m_result, rownr, i); 
-} 
-
-
-/******
-   Based on invmatrix.c, project ESPRIT 612 by Th. Koster.
-******/
-hmat2_t *
-m_inv2(matrix, m_result)
-const hmat2_t *matrix;
-hmat2_t *m_result; 
-{
-   hmat2_t m_input;
-   int i, j;
-
-   m_result = gm_ALLOC(hmat2_t, m_result, "m_inv2()");
-
-   for(i=0; i<3; i++)
-     for(j=0; j<3; j++)
-        m_elem(*m_result, i, j) = (i!=j) ? 0.0 : 1.0;
-
-   /* save contence of matrix */
-   m_input = *matrix;
-
-   /* reduce row for row to transform the */
-   /* input matrix to an elementary matrix */
-   for(i=0;i<3;i++)
-        /* reduce this row to a row of an elementary matrix */
-     reduce_row2(&m_input, m_result, i);
-
-   return  m_result;
-} 
-
-hmat2_t *
-m_tra2(matrix, m_result)
-const hmat2_t *matrix;
-hmat2_t *m_result;
-{
-   m_result = gm_ALLOC(hmat2_t, m_result, "m_tra2()");
-
-   if(m_result != matrix)
-   {
-     int i,j;
-
-     for(i=0; i<3; i++)
-        for(j=0; j<3; j++)
-          m_elem(*m_result, i, j) = m_elem(*matrix, j, i);
-   }
-   else
-   {
-     double  buf[3];
-
-     buf[0] = m_elem(*matrix, 1, 0);
-     buf[1] = m_elem(*matrix, 2, 0);
-     buf[2] = m_elem(*matrix, 2, 1);
-
-     m_elem(*m_result, 1, 0) = m_elem(*matrix, 0, 1);
-     m_elem(*m_result, 2, 0) = m_elem(*matrix, 0, 2);
-     m_elem(*m_result, 2, 1) = m_elem(*matrix, 1, 2);
-
-     m_elem(*m_result, 0, 1) = buf[0]; 
-     m_elem(*m_result, 0, 2) = buf[1];
-     m_elem(*m_result, 1, 2) = buf[2];
-
-   };
-
-   return m_result;
-}
-
-
-hmat2_t *
-mm_add2(matrixA, matrixB, m_result)
-const hmat2_t *matrixA;
-const hmat2_t *matrixB;
-hmat2_t *m_result;
-{
-   int row, col;
-
-   m_result = gm_ALLOC(hmat2_t, m_result, "mm_add2()");
-
-   for(row=0; row<3; row++)
-     for(col=0; col<3; col++)
-        m_elem(*m_result, row, col) = m_elem(*matrixA, row, col) + m_elem(*matrixB, row, col);
-
-	return m_result;
-}
-
-
-hmat2_t *
-mm_mul2(matrixA, matrixB, m_result)
-const hmat2_t *matrixA;
-const hmat2_t *matrixB;
-hmat2_t *m_result;
-{
-   int row, col, which_matrix; /* Is m_result used in place \
-                and if which matrix equals \
-                m_result */
-   hmat2_t buf;
-
-   if(m_result == matrixA)
-   { 
-     m_result = &buf;
-     which_matrix = 1;
-   }
-   else
-     if(m_result == matrixB)
-     {
-        m_result = &buf;
-        which_matrix = 2;
-     }
-     else 
-     {
-        m_result = gm_ALLOC(hmat2_t, m_result, "mm_mul2()");
-        which_matrix = 0;
-     };
-
-   for(row=0; row<3; row++)
-     for(col=0; col<3; col++)
-        m_elem(*m_result, row, col) = m_elem(*matrixA, row, 0) * m_elem(*matrixB, 0, col) +
-                  m_elem(*matrixA, row, 1) * m_elem(*matrixB, 1, col) + m_elem(*matrixA, row, 2) *
-	 	  m_elem(*matrixB, 2, col); 
-
-   switch(which_matrix)
-   {
-     case 0 : return  m_result;
-     case 1 : /* m_cpy2(m_result, matrixA); */
-              *(hmat2_t *)matrixA = *m_result;
-              return  (hmat2_t *)matrixA;
-     case 2 : /* m_cpy2(m_result, matrixB); */
-              *(hmat2_t *)matrixB = *m_result;
-              return (hmat2_t *)matrixB;
-   };
-	error("This should not happen! %s %d\n", __FILE__, __LINE__ );
-	return m_result;	/* garbage... */
-}
-
-
-hmat2_t *
-mm_sub2(matrixA, matrixB, m_result)
-const hmat2_t *matrixA;
-const hmat2_t *matrixB;
-hmat2_t *m_result;
-{
-   int row, col;
-
-   m_result = gm_ALLOC(hmat2_t, m_result, "mm_sub2()");
-
-   for(row=0; row<3; row++)
-     for(col=0; col<3; col++)
-        m_elem(*m_result, row, col) = m_elem(*matrixA, row, col) - m_elem(*matrixB, row, col);
-
-   return  m_result;
-}
-
-
-hmat2_t *
-mtmm_mul2(matrixA, matrixB, m_result)
-const hmat2_t *matrixA;
-const hmat2_t *matrixB;
-hmat2_t *m_result;
-{
-   hmat2_t help;
-
-   m_result = gm_ALLOC(hmat2_t, m_result, "mtmm_mul2()");
-
-   m_tra2(matrixA, &help);
-
-   mm_mul2(&help, matrixB, &help);
-   mm_mul2(&help, matrixA, m_result);
-
-   return  m_result;
-}
-
-
-hmat2_t *
-sm_mul2(scalar, matrix, m_result)
-double  scalar;
-const hmat2_t *matrix;
-hmat2_t *m_result;
-{
-   int row, col;
-
-   m_result = gm_ALLOC(hmat2_t, m_result, "sm_mul2()");
-
-   for(row=0; row<3; row++)
-     for(col=0; col<3; col++)
-        m_elem(*m_result, row, col) = scalar * m_elem(*matrix, row, col);
-
-   return  m_result;
-}
-
-
-hmat2_t *
-vvt_mul2(vectorA, vectorB, m_result)
-const hvec2_t *vectorA;
-const hvec2_t *vectorB;
-hmat2_t *m_result;
-{
-   int row, col;
-
-   m_result = gm_ALLOC(hmat2_t, m_result, "vvt_mul2()");
-
-   for(row=0; row<3; row++)
-     for(col=0; col<3; col++)
-        m_elem(*m_result, row, col) = v_elem(*vectorA, row) * v_elem(*vectorB, col);
-
-   return  m_result;
-}
-
-hvec2_t *
-mv_mul2(matrix, vector, v_result)
-const hmat2_t *matrix;
-const hvec2_t *vector;
-hvec2_t *v_result;
-{
-   int row, inplace;
-   hvec2_t buf;
-
-   if(v_result == vector)
-   {
-     v_result = &buf;
-     inplace = 1;
-   }
-   else
-   {
-     v_result = gm_ALLOC(hvec2_t, v_result, "mv_mul2()");
-     inplace = 0;
-   };
-
-   for(row=0; row<3; row++)
-        v_elem(*v_result, row) = m_elem(*matrix, row, 0) * v_elem(*vector, 0) +
-                                 m_elem(*matrix, row, 1) * v_elem(*vector, 1) +
-               			 m_elem(*matrix, row, 2) * v_elem(*vector, 2); 
-   
-   if(inplace)
-   {
-     /* v_cpy2(v_result, vector); */
-     *(hvec2_t *)vector = *v_result;
-
-     return  (hvec2_t *)vector;
-   };
-
-   return  v_result;
-}
-
-
-hvec2_t *
-sv_mul2(scalar, vector, v_result)
-double  scalar;
-const hvec2_t *vector;
-hvec2_t *v_result;
-{
-   v_result = gm_ALLOC(hvec2_t, v_result, "sv_mul2()");
-
-   v_x(*v_result) = v_x(*vector) * scalar;
-   v_y(*v_result) = v_y(*vector) * scalar;
-   v_w(*v_result) = v_w(*vector);
-
-   return  v_result;
-}
-
-hvec2_t *
-v_homo2(vector, v_result)
-const hvec2_t *vector;
-hvec2_t *v_result;
-{
-   v_result = gm_ALLOC(hvec2_t, v_result, "v_homo2()");
-
-   v_x(*v_result) = gm_DIV(v_x(*vector), v_w(*vector), "v_homo2()");
-   v_y(*v_result) = v_y(*vector) / v_w(*vector);
-   v_w(*v_result) = 1.0;
-
-   return v_result;
-}
-
-hvec2_t *
-v_norm2(vector, v_result)
-const hvec2_t *vector;
-hvec2_t *v_result;
-{
-   double  length = sqrt(v_x(*vector) * v_x(*vector) +
-           v_y(*vector) * v_y(*vector));
-
-   v_result = gm_ALLOC(hvec2_t, v_result, "v_norm2()");
-
-   v_x(*v_result) = gm_DIV(v_x(*vector), length, "v_norm2()");
-   v_y(*v_result) = v_y(*vector) / length;
-   v_w(*v_result) = v_w(*vector) / length;
-
-   return  v_result;
-}
-
-
-hvec2_t *
-vv_add2(vectorA, vectorB, v_result)
-const hvec2_t *vectorA;
-const hvec2_t *vectorB;
-hvec2_t  *v_result;
-{
-   v_result = gm_ALLOC(hvec2_t, v_result, "vv_add2()");
-
-   v_x(*v_result) = v_x(*vectorA) + v_x(*vectorB);
-   v_y(*v_result) = v_y(*vectorA) + v_y(*vectorB);
-   v_w(*v_result) = v_w(*vectorA) + v_w(*vectorB);
-
-   return  v_result;
-}
-
-
-hvec2_t *
-vv_sub2(vectorA, vectorB, v_result)
-const hvec2_t *vectorA;
-const hvec2_t *vectorB;
-hvec2_t  *v_result;
-{
-   v_result = gm_ALLOC(hvec2_t, v_result, "vv_sub2()");
-
-   v_x(*v_result) = v_x(*vectorA) - v_x(*vectorB);
-   v_y(*v_result) = v_y(*vectorA) - v_y(*vectorB);
-   v_w(*v_result) = v_w(*vectorA) - v_w(*vectorB);
-
-
-   return  v_result;
-}
-
-
-/****** Level 3 : Basic lineair algebra : 3D homogeneous
-coordinates ******/
-
-/***** Function is optimized, see below !!!
-double
-m_det3(matrix)
-const hmat3_t *matrix;
-{
-   hmat2_t det2;
-   double  result=0.0;
-   int col, count, row, row_det2, factor=1.0;
-
-   for(count=0; count<4; count++)
-   {
-     row_det2 = 0;
-     for(row=0; row<4; row++)
-        if(count != row)
-        {
-          for(col=1; col<4; col++)
-             m_elem(det2, row_det2, col-1) = m_elem(*matrix, row, col);
-          row_det2++;
-        };
-     result += m_elem(*matrix, count, 0) * m_det2(&det2) * factor;
-     factor = -factor;
-   };
-   return  result;
-}
-*/
-
-/* used by m_det3() */
-/* return the under-determinant of a 4*4 matrix */
-static  double
-det2_dyn(matrix, row_not)
-const hmat3_t *matrix;
-int row_not;
-{
-   int row[3], count, help=0;
-
-   for(count=0; count<4; count++)
-     if(count != row_not)
-        row[help++] = count;
-
-   return
-   m_elem(*matrix,row[0],1) * (m_elem(*matrix,row[1],2) *
-   m_elem(*matrix,row[2],3) -
-   m_elem(*matrix,row[1],3) * m_elem(*matrix,row[2],2)) -
-   m_elem(*matrix,row[1],1) * (m_elem(*matrix,row[0],2) *
-   m_elem(*matrix,row[2],3) -
-   m_elem(*matrix,row[0],3) * m_elem(*matrix,row[2],2)) + 
-   m_elem(*matrix,row[2],1) * (m_elem(*matrix,row[0],2) *
-   m_elem(*matrix,row[1],3) -
-   m_elem(*matrix,row[0],3) * m_elem(*matrix,row[1],2));
-}
-
-double
-m_det3(matrix)
-const hmat3_t *matrix;
-{
-   double  result=0.0;
-   int row, factor=-1;
-
-   for(row=0; row<4; row++)
-     result += m_elem(*matrix, row, 0) * det2_dyn(matrix, row) *
-         (factor *= -1);
-
-   return result;
-}
-
-double
-v_len3(vector)
-const hvec3_t *vector;
-{
-   double  result;
-
-   result = ((sqrt(v_x(*vector) * v_x(*vector) + 
-            v_y(*vector) * v_y(*vector) +
-            v_z(*vector) * v_z(*vector))));
-
-   return v_w(*vector) != 0.0 ? result / v_w(*vector) : result;
-}
-
-
-double
-vtmv_mul3(vector, matrix)
-const hvec3_t *vector;
-const hmat3_t *matrix;
-{
-
-   return
-     ((v_x(*vector) * m_elem(*matrix, 0, 0) +
-      v_y(*vector) * m_elem(*matrix, 1, 0) +
-      v_z(*vector) * m_elem(*matrix, 2, 0) +
-      v_w(*vector) * m_elem(*matrix, 3, 0)) * 
-      v_x(*vector)) +
-     ((v_x(*vector) * m_elem(*matrix, 0, 1) +
-      v_y(*vector) * m_elem(*matrix, 1, 1) +
-      v_z(*vector) * m_elem(*matrix, 2, 1) +
-      v_w(*vector) * m_elem(*matrix, 3, 1)) *
-      v_y(*vector)) +
-     ((v_x(*vector) * m_elem(*matrix, 0, 2) +
-      v_y(*vector) * m_elem(*matrix, 1, 2) +
-      v_z(*vector) * m_elem(*matrix, 2, 2) +
-      v_w(*vector) * m_elem(*matrix, 3, 2)) *
-      v_z(*vector)) +
-     ((v_x(*vector) * m_elem(*matrix, 0, 3) +
-      v_y(*vector) * m_elem(*matrix, 1, 3) +
-      v_z(*vector) * m_elem(*matrix, 2, 3) +
-      v_w(*vector) * m_elem(*matrix, 3, 3)) *
-      v_w(*vector));
-}
-
-double
-vv_inprod3(vectorA, vectorB)
-const hvec3_t *vectorA;
-const hvec3_t *vectorB;
-{  double  result, div;
-
-   result = v_x(*vectorA) * v_x(*vectorB) + 
-            v_y(*vectorA) * v_y(*vectorB) +
-            v_z(*vectorA) * v_z(*vectorB); 
-   div = 1.0;
-   if(v_w(*vectorA) != 0.0 && v_w(*vectorA) != 1.0)
-     div *= v_w(*vectorA);
-   if(v_w(*vectorB) != 0.0 && v_w(*vectorB) != 1.0)
-     div *= v_w(*vectorB);
-   if (div != 1.0) return result/div;
-
-   return result;
-}
-
-
-/* Used by "m_inv3()" */
-static void 
-submultiples3(m_input, m_result, rownr, workingrow)
-hmat3_t *m_input, *m_result;
-int  rownr, workingrow;
-{
-   int i;
-   double  subtractionfactor;
-   
-   if((subtractionfactor = m_elem(*m_input, workingrow, rownr)) != 0.0)
-   {
-     for(i=rownr; i<4; i++)
-        m_elem(*m_input,workingrow,i) -= m_elem(*m_input,rownr,i) * subtractionfactor;
-
-
-     for(i=0; i<4; i++)
-        m_elem(*m_result,workingrow,i) -= m_elem(*m_result,rownr,i) * subtractionfactor;
-
-   };
-} 
-
-/* Used by "m_inv3()" */
-static  void
-interchangerow3(m_input, m_result, rownr)
-hmat3_t *m_input, *m_result;
-int rownr;
-{
-   int nextelement = rownr+1, i;
-   double  buffer;
-
-   while(m_elem(*m_input, nextelement, rownr) == 0.0) 
-     if(++nextelement == 4)
-        gm_error(MATSING, "m_inv3()");
-
-   /* interchange one rowelement with an element of */
-   /* a row with a nonzeroentry in the same column */
-   for(i=0; i<4; i++)
-   {
-     buffer = m_elem(*m_input, nextelement, i);
-     m_elem(*m_input, nextelement, i) = m_elem(*m_input, rownr, i);
-     m_elem(*m_input, rownr, i) = buffer;
-     
-     buffer = m_elem(*m_result, nextelement, i);
-     m_elem(*m_result, nextelement, i) = m_elem(*m_result, rownr, i);
-     m_elem(*m_result, rownr, i) = buffer;
-   };
-}
-
-/* Used by "m_inv3()" */
-static  void
-reduce_row3(m_input, m_result, rownr)
-hmat3_t *m_input, *m_result;
-int rownr;
-{
-   int i;
-   double  factor;
-
-   if(m_elem(*m_input, rownr, rownr) == 0.0)
-     /* interchange this row with another row to  
-       bring a nonzero entry in the main diagonal */
-     interchangerow3(m_input, m_result, rownr);
-
-   /* introduce a leading one by dividing the whole row */
-   factor = m_elem(*m_input, rownr, rownr);
-   for(i=rownr; i<4; i++)
-     m_elem(*m_input, rownr, i) /= factor;
-   for(i=0; i<4; i++)
-     m_elem(*m_result, rownr, i) /= factor;
-     
-
-   for(i=0; i<4; i++)
-        if(i != rownr)
-     /* subtract suitable multiples of this row to the other rows */
-     /* so that all other entries in this column become zeros.  */
-        submultiples3(m_input, m_result, rownr, i); 
-} 
-
-
-/******
-   Based on invmatrix.c, project ESPRIT 612 by Th. Koster.
-******/
-hmat3_t *
-m_inv3(matrix, m_result)
-const hmat3_t *matrix;
-hmat3_t *m_result; 
-{
-   hmat3_t m_input;
-   int i;
-
-   m_result = m_unity3(m_result);
-
-   /* save contence of matrix */
-   m_input = *matrix;
-
-   /* reduce row for row to transform the */
-   /* input matrix to an elementary matrix */
-   for(i=0;i<4;i++)
-        /* reduce this row to a row of an elementary matrix */
-     reduce_row3(&m_input, m_result, i);
-
-   return  m_result;
-} 
-
-hmat3_t *
-m_tra3(matrix, m_result)
-const hmat3_t *matrix;
-hmat3_t *m_result; 
-{
-   m_result = gm_ALLOC(hmat3_t, m_result, "m_tra3()");
-
-   if(m_result != matrix)
-   {
-     int i, j;
-
-     m_result = gm_ALLOC(hmat3_t, m_result, "m_tra3()");
-
-     for(i=0; i<4; i++)
-        for(j=0; j<4; j++)
-          m_elem(*m_result, i, j) = m_elem(*matrix, j, i);
-   }
-   else
-   {
-     double  buf[6];
-
-     buf[0] = m_elem(*matrix, 1, 0);
-     buf[1] = m_elem(*matrix, 2, 0);
-     buf[2] = m_elem(*matrix, 2, 1);
-     buf[3] = m_elem(*matrix, 3, 0);
-     buf[4] = m_elem(*matrix, 3, 1);
-     buf[5] = m_elem(*matrix, 3, 2);
-
-
-     m_elem(*m_result, 1, 0) = m_elem(*matrix, 0, 1);
-     m_elem(*m_result, 2, 0) = m_elem(*matrix, 0, 2);
-     m_elem(*m_result, 2, 1) = m_elem(*matrix, 1, 2);
-     m_elem(*m_result, 3, 0) = m_elem(*matrix, 0, 3);
-     m_elem(*m_result, 3, 1) = m_elem(*matrix, 1, 3);
-     m_elem(*m_result, 3, 2) = m_elem(*matrix, 2, 3);
-
-     m_elem(*m_result, 0, 1) = buf[0]; 
-     m_elem(*m_result, 0, 2) = buf[1];
-     m_elem(*m_result, 0, 3) = buf[3];
-     m_elem(*m_result, 1, 2) = buf[2];
-     m_elem(*m_result, 1, 3) = buf[4];
-     m_elem(*m_result, 2, 3) = buf[5];
-   };
-
-   return m_result;
-}
-
-
-hmat3_t *
-mm_add3(matrixA, matrixB, m_result)
-const hmat3_t *matrixA;
-const hmat3_t *matrixB;
-hmat3_t *m_result;
-{
-   int row, col;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "mm_add3()");
-
-   for(row=0; row<4; row++)
-     for(col=0; col<4; col++)
-        m_elem(*m_result, row, col) = m_elem(*matrixA, row, col) + m_elem(*matrixB, row, col);
-
-	return m_result;
-}
-
-
-hmat3_t *
-mm_mul3(matrixA, matrixB, m_result)
-const hmat3_t *matrixA;
-const hmat3_t *matrixB;
-hmat3_t *m_result;
-{
-   int row, col, which_matrix;
-   hmat3_t buf;
-
-   if(m_result == matrixA)
-   { 
-     m_result = &buf;
-     which_matrix = 1;
-   }
-   else
-     if(m_result == matrixB)
-     {
-        m_result = &buf;
-        which_matrix = 2;
-     }
-     else 
-     {
-        m_result = gm_ALLOC(hmat3_t, m_result, "mm_mul3()");
-        which_matrix = 0;
-     };
-
-   for(row=0; row<4; row++)
-     for(col=0; col<4; col++)
-        m_elem(*m_result, row, col) = m_elem(*matrixA, row, 0) * m_elem(*matrixB, 0, col) +
-                  m_elem(*matrixA, row, 1) * m_elem(*matrixB, 1, col) + m_elem(*matrixA, row, 2) *
-		  m_elem(*matrixB, 2, col) + m_elem(*matrixA, row, 3) * m_elem(*matrixB, 3, col); 
-
-   switch(which_matrix)
-   {
-     case 0 : return  m_result;
-     case 1 : /* m_cpy3(m_result, matrixA); */
-              * (hmat3_t *)matrixA = *m_result;
-              return  (hmat3_t *)matrixA;
-     case 2 : /* m_cpy3(m_result, matrixB); */
-              *(hmat3_t *)matrixB = *m_result;
-              return (hmat3_t *)matrixB;
-   };
-	error("This should not happen! %s %d\n", __FILE__, __LINE__ );
-	return m_result;	/* garbage... */
-}
-
-
-hmat3_t *
-mm_sub3(matrixA, matrixB, m_result)
-const hmat3_t *matrixA;
-const hmat3_t *matrixB;
-hmat3_t *m_result;
-{
-   int row, col;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "mm_sub3()");
-
-   for(row=0; row<4; row++)
-     for(col=0; col<4; col++)
-        m_elem(*m_result, row, col) = m_elem(*matrixA, row, col) - m_elem(*matrixB, row, col);
-
-   return  m_result;
-}
-
-
-hmat3_t *
-mtmm_mul3(matrixA, matrixB, m_result)
-const hmat3_t *matrixA;
-const hmat3_t *matrixB;
-hmat3_t *m_result;
-{
-   hmat3_t help;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "mtmm_mul3()");
-
-   m_tra3(matrixA, &help);
-
-   mm_mul3(&help, matrixB, &help);
-   mm_mul3(&help, matrixA, m_result);
-
-   return  m_result;
-}
-
-
-hmat3_t *
-sm_mul3(scalar, matrix, m_result)
-double  scalar;
-const hmat3_t *matrix;
-hmat3_t *m_result;
-{
-   int row, col;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "sm_mul3()");
-
-   for(row=0; row<4; row++)
-     for(col=0; col<4; col++)
-        m_elem(*m_result, row, col) = scalar * m_elem(*matrix, row, col);
-
-   return  m_result;
-}
-
-
-hvec3_t *
-mv_mul3(matrix, vector, v_result)
-const hmat3_t *matrix;
-const hvec3_t *vector;
-hvec3_t *v_result;
-{
-   int row, inplace;
-   hvec3_t buf;
-
-   if(v_result == vector)
-   {
-     v_result = &buf;
-     inplace = 1;
-   }
-   else
-   {
-     v_result = gm_ALLOC(hvec3_t, v_result, "mv_mul3()");
-     inplace = 0;
-   };
-
-   for(row=0; row<4; row++)
-        v_elem(*v_result, row) = m_elem(*matrix, row, 0) *
-	v_elem(*vector, 0) + m_elem(*matrix, row, 1) *
-	v_elem(*vector, 1) + m_elem(*matrix, row, 2) *
-	v_elem(*vector, 2) + m_elem(*matrix, row, 3) *
-	v_elem(*vector, 3); 
-   
-   if(inplace)
-   {
-     v_cpy3(v_result, (hvec3_t *)vector);
-     return (hvec3_t *) vector;
-   };
-
-   return  v_result;
-}
-
-
-hvec3_t *
-sv_mul3(scalar, vector, v_result)
-double  scalar;
-const hvec3_t *vector;
-hvec3_t *v_result;
-{
-   v_result = gm_ALLOC(hvec3_t, v_result, "sv_mul3()");
-
-   v_x(*v_result) = v_x(*vector) * scalar;
-   v_y(*v_result) = v_y(*vector) * scalar;
-   v_z(*v_result) = v_z(*vector) * scalar;
-   v_w(*v_result) = v_w(*vector);
-
-   return  v_result;
-}
-
-hvec3_t *
-v_homo3(vector, v_result)
-const hvec3_t *vector;
-hvec3_t *v_result;
-{
-   v_result = gm_ALLOC(hvec3_t, v_result, "v_homo3()");
-
-   v_x(*v_result) = gm_DIV(v_x(*vector), v_w(*vector), "v_homo3()");
-   v_y(*v_result) = v_y(*vector) / v_w(*vector);
-   v_z(*v_result) = v_z(*vector) / v_w(*vector);
-   v_w(*v_result) = 1.0;
-
-   return v_result;
-}
-
-
-hvec3_t *
-v_norm3(vector, v_result)
-const hvec3_t *vector;
-hvec3_t *v_result;
-{
-   double  length = sqrt(v_x(*vector) * v_x(*vector) + 
-   	                 v_y(*vector) * v_y(*vector) +
-           		 v_z(*vector) * v_z(*vector));
-
-   v_result = gm_ALLOC(hvec3_t, v_result, "v_norm3()");
-
-/*   length = sqrt(v_x(*vector) * v_x(*vector) + 
-//        	 v_y(*vector) * v_y(*vector) +
-//        	 v_z(*vector) * v_z(*vector));			*/
-
-   v_x(*v_result) = gm_DIV(v_x(*vector), length, "v_norm2()");
-   v_y(*v_result) = v_y(*vector) / length;
-   v_z(*v_result) = v_z(*vector) / length;
-   v_w(*v_result) = v_w(*vector) / length;
-
-   return  v_result;
-}
-
-hvec3_t *
-vv_add3(vectorA, vectorB, v_result)
-const hvec3_t *vectorA;
-const hvec3_t *vectorB;
-hvec3_t *v_result;
-{
-   v_result = gm_ALLOC(hvec3_t, v_result, "vv_add3()");
-
-   v_x(*v_result) = v_x(*vectorA) + v_x(*vectorB);
-   v_y(*v_result) = v_y(*vectorA) + v_y(*vectorB);
-   v_z(*v_result) = v_z(*vectorA) + v_z(*vectorB);
-   v_w(*v_result) = v_w(*vectorA) + v_w(*vectorB);
-
-   return  v_result;
-}
-
-
-hvec3_t *
-vv_cross3(vectorA, vectorB, v_result)
-const hvec3_t *vectorA;
-const hvec3_t *vectorB;
-hvec3_t *v_result;
-{
-   int which_vec; /* Is v_result used in place, if so which \
-		     vectors are equal ? */
-         
-   hvec3_t buf;
-
-   if(v_result == vectorA)
-   {
-     v_result = &buf;
-     which_vec = 1;
-   }
-   else
-     if(v_result == vectorB)
-     {
-        v_result = &buf;
-        which_vec = 2;
-     }
-     else
-     {
-        v_result = gm_ALLOC(hvec3_t, v_result, "vv_cross3()");
-        which_vec = 0;
-     };
-
-   v_x(*v_result) = v_y(*vectorA) * v_z(*vectorB) -
-            v_z(*vectorA) * v_y(*vectorB);
-   v_y(*v_result) = v_z(*vectorA) * v_x(*vectorB) -
-            v_x(*vectorA) * v_z(*vectorB);
-   v_z(*v_result) = v_x(*vectorA) * v_y(*vectorB) -
-            v_y(*vectorA) * v_x(*vectorB);
-   v_w(*v_result) = v_w(*vectorA) * v_w(*vectorB);
-
-   switch(which_vec)
-   {
-     case 0 : return v_result;
-     case 1 : /* v_cpy3(v_result, vectorA); */
-              *(hvec3_t *)vectorA = *v_result;
-              return (hvec3_t *)vectorA;
-     case 2 : /* v_cpy3(v_result, vectorB); */
-              *(hvec3_t *)vectorB = *v_result;
-              return (hvec3_t *)vectorB;
-   };
-	error("This should not happen! %s %d\n", __FILE__, __LINE__ );
-	return v_result;	/* garbage... */
-}
-
-hvec3_t *
-vv_sub3(vectorA, vectorB, v_result)
-const hvec3_t *vectorA;
-const hvec3_t *vectorB;
-hvec3_t *v_result;
-{
-   v_result = gm_ALLOC(hvec3_t, v_result, "vv_sub3()");
-
-   v_x(*v_result) = v_x(*vectorA) - v_x(*vectorB);
-   v_y(*v_result) = v_y(*vectorA) - v_y(*vectorB);
-   v_z(*v_result) = v_z(*vectorA) - v_z(*vectorB);
-   v_w(*v_result) = v_w(*vectorA) - v_w(*vectorB);
-
-   return  v_result;
-}
-
-
-hmat3_t *
-vvt_mul3(vectorA, vectorB, m_result)
-const hvec3_t *vectorA;
-const hvec3_t *vectorB;
-hmat3_t *m_result;
-{
-   int row, col;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "vvt_mul3()");
-
-   for(row=0; row<4; row++)
-     for(col=0; col<4; col++)
-        m_elem(*m_result, row, col) = v_elem(*vectorA, row) * v_elem(*vectorB, col);
-
-   return  m_result;
-}
-
-
-/****** Level 4 : Elementary transformations ******/
-hmat2_t *
-miraxis2(axis, m_result)
-b_axis  axis;
-hmat2_t *m_result;
-{
-   int i, j;
-
-   m_result = gm_ALLOC(hmat2_t, m_result, "miraxis2()");
-
-   for(i=0; i<3; i++)
-     for(j=0; j<3; j++)
-        m_elem(*m_result, i, j) = (i != j) ? 0.0 : 1.0;
-
-   if(axis == X_AXIS)
-     m_elem(*m_result, 1, 1) = -1.0;
-   else
-     m_elem(*m_result, 0, 0) = -1.0;
-   
-   return  m_result;
-}
-
-
-hmat2_t *
-mirorig2(m_result)
-hmat2_t *m_result;
-{
-   int i, j;
-
-   m_result = gm_ALLOC(hmat2_t, m_result, "mirorig()");
-
-   for(i=0; i<3; i++)
-     for(j=0; j<3; j++)
-       m_elem(*m_result, i, j) = (i != j) ? 0.0 : -1.0;
-
-   m_elem(*m_result, 2, 2) = 1.0;
-
-  return m_result;
-}
-
-hmat2_t *
-rot2(rotation, m_result)
-double  rotation;
-hmat2_t *m_result;
-{
-   m_result = gm_ALLOC(hmat2_t, m_result, "rot2()");
-
-   m_elem(*m_result, 0, 0) = m_elem(*m_result, 1, 1) = cos(rotation);
-   m_elem(*m_result, 1, 0) = sin(rotation);
-   m_elem(*m_result, 0, 1) = -m_elem(*m_result, 1, 0);
-
-   m_elem(*m_result, 2, 0) = m_elem(*m_result, 2, 1) = 
-   m_elem(*m_result, 0, 2) = m_elem(*m_result, 1, 2) = 0.0;
-   m_elem(*m_result, 2, 2) = 1.0;
-
-   return m_result;
-}
-
-
-hmat2_t *
-scaorig2(scale, m_result)
-double  scale;
-hmat2_t *m_result;
-{
-   int i, j;
-
-   m_result = gm_ALLOC(hmat2_t, m_result, "scaorig2()");
-
-   for(i=0; i<3; i++)
-     for(j=0; j<3; j++)
-        m_elem(*m_result, i, j) = (i != j) ? 0.0 : scale;
-
-   m_elem(*m_result, 2, 2) = 1.0;
-
-   return m_result;
-}
-
-
-hmat2_t *
-scaxis2(scale, axis, m_result)
-double  scale;
-b_axis  axis;
-hmat2_t *m_result;
-{
-#ifdef notdef
-   int i, j;
-
-   m_result = gm_ALLOC(hmat2_t, m_result, "miraxis2()");
-
-   for(i=0; i<3; i++)
-     for(j=0; j<3; j++)
-        m_elem(*m_result, i, j) = (i != j) ? 0.0 : scale;
-#else
-	m_result = m_unity2(m_result);
-#endif
-
-   if(axis == X_AXIS)
-     m_elem(*m_result, 1, 1) = scale;
-   else
-     m_elem(*m_result, 0, 0) = scale;
-   
-   return  m_result;
-}
-
-
-hmat2_t *
-transl2(translation, m_result)
-const hvec2_t *translation;
-hmat2_t *m_result;
-{
-   int i, j;
-
-   m_result = gm_ALLOC(hmat2_t, m_result, "transl2()");
-
-   for(i=0; i<3; i++)
-     for(j=0; j<2; j++)
-        m_elem(*m_result, i, j) = (i != j) ? 0.0 : 1.0;
-
-   m_elem(*m_result, 0, 2) = v_x(*translation);
-   m_elem(*m_result, 1, 2) = v_y(*translation);
-   m_elem(*m_result, 2, 2) = 1.0;
-
-   return  m_result;
-}
-
-
-hmat3_t *
-miraxis3(axis, m_result)
-b_axis  axis;
-hmat3_t *m_result;
-{
-   int i,j;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "miraxis3()");
-
-   for(i=0; i<4; i++)
-     for(j=0; j<4; j++)
-        m_elem(*m_result, i, j) = (i != j) ? 0.0 : (i != (int)axis) ? 1.0 : -1.0;
-
-   m_elem(*m_result, 3, 3) = 1.0;
-
-   return  m_result;
-}
-
-
-hmat3_t *
-mirorig3(m_result)
-hmat3_t *m_result;
-{
-   int i, j;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "mirorig3()");
-
-   for(i=0; i<4; i++)
-     for(j=0; j<4; j++)
-       m_elem(*m_result, i, j) = (i != j) ? 0.0 : -1.0;
-
-   m_elem(*m_result, 3, 3) = 1.0;
-
-   return m_result;
-}
-
-hmat3_t *
-mirplane3(plane, m_result)
-b_axis  plane;
-hmat3_t *m_result;
-{
-   int i, j;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "mirplane3()");
-   for(i=0; i<4; i++)
-     for(j=0; j<4; j++)
-        m_elem(*m_result, i, j) = (i != j) ? 0.0 : 1.0;
-
-   m_elem(*m_result, (int)plane, (int)plane) = -1.0;
-
-   return  m_result;
-}
-        
-   
-hmat3_t *
-prjorthaxis(axis, m_result)
-b_axis  axis;
-hmat3_t *m_result;
-{
-#ifndef notdef
-	/* An orthographic projection, handled similar to a perspective
-	 * projection, is a unity operator!
-	 * So the coordinate of the axis over which is projected is the
-	 * distance from the projection plane to the input vector
-	 */
-	m_result = m_unity3(m_result);
-#else	/* notdef */
-   int i, j;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "prjorthaxis()");
-
-   for(i=0; i<4; i++)
-     for(j=0; j<4; j++)
-        m_elem(*m_result, i, j) = (i!=j) ? 0.0 : 1.0;
-
-   m_elem(*m_result, (int)axis, (int)axis) = 0.0;
-#endif	/* notdef */
-
-   return  m_result;
-}
-
-
-hmat3_t *
-prjpersaxis(axis, m_result)
-b_axis  axis;
-hmat3_t *m_result;
-{
-#ifdef notdef
-   hvec3_t x, y, z, viewdir;
-   int i;
-#endif
-
-   m_result = m_unity3(m_result);
-
-	m_elem(*m_result,3,3) = 0.0;
-
-   switch(axis)
-   {
-     case X_AXIS :
-		m_elem(*m_result,3,0) = 1.0;
-                   break;
-     case Y_AXIS :
-		m_elem(*m_result,3,1) = 1.0;
-                   break;
-     case Z_AXIS : 
-		m_elem(*m_result,3,2) = 1.0;
-                   break;
-   };
-
-   return m_result;
-}
-
-
-
-hmat3_t *
-rot3(rotation, axis, m_result)
-double  rotation;
-b_axis  axis;
-hmat3_t *m_result;
-{
-   int i, j;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "rot3()");
-
-   for(i=0; i<4; i++)
-     for(j=0; j<4; j++)
-        m_elem(*m_result, i, j) = (i!=j) ? 0.0 : 1.0; 
-
-   i = ((int)axis + 1)%3;
-   j = ((int)axis + 2)%3;
-   m_elem(*m_result, i, i) = m_elem(*m_result, j, j) = cos(rotation);
-   m_elem(*m_result, j, i) = sin(rotation);
-   m_elem(*m_result, i, j) = -m_elem(*m_result, j, i);
-
-   return  m_result;
-}
-
-hmat3_t *
-scaorig3(scale, m_result)
-double  scale;
-hmat3_t *m_result;
-{
-   int i, j;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "scaorig2()");
-
-   for(i=0; i<4; i++)
-     for(j=0; j<4; j++)
-        m_elem(*m_result, i, j) = (i != j) ? 0.0 : scale;
-
-   m_elem(*m_result, 3, 3) = 1.0;
-
-   return  m_result;
-}
-
-
-hmat3_t *
-scaplane3(scale, plane, m_result)
-double  scale;
-b_axis  plane;
-hmat3_t *m_result;
-{
-   int i, j;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "scaplane3()");
-   for(i=0; i<4; i++)
-     for(j=0; j<4; j++)
-        m_elem(*m_result, i, j) = (i != j) ? 0.0 : 1.0;
-
-   m_elem(*m_result, (int)plane, (int)plane) = scale;
-
-   return  m_result;
-}
-
-
-hmat3_t *
-scaxis3(scale, axis, m_result)
-double  scale;
-b_axis  axis;
-hmat3_t *m_result;
-{
-#ifdef notdef
-   int i,j;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "scaxis3()");
-
-   for(i=0; i<4; i++)
-     for(j=0; j<4; j++)
-        m_elem(*m_result, i, j) = (i != j) ? 0.0 : (i != (int)axis) ? -1.0 : scale;
-
-   m_elem(*m_result, 3, 3) = 1.0;
-#else
-	m_result = m_unity3(m_result);
-
-	m_elem(*m_result, axis, axis) = scale;
-#endif
-
-   return  m_result;
-}
-
-
-hmat3_t *
-transl3(translation, m_result)
-const hvec3_t *translation;
-hmat3_t *m_result;
-{
-   int i, j;
-
-   m_result = gm_ALLOC(hmat3_t, m_result, "transl2()");
-
-   for(i=0; i<4; i++)
-     for(j=0; j<3; j++)
-        m_elem(*m_result, i, j) = (i != j) ? 0.0 : 1.0;
-
-   m_elem(*m_result, 0, 3) = v_x(*translation);
-   m_elem(*m_result, 1, 3) = v_y(*translation);
-   m_elem(*m_result, 2, 3) = v_z(*translation);
-   m_elem(*m_result, 3, 3) = 1.0;
-
-   return  m_result;
-}
+/*
+  Revision 1.6  2005/03/12 16:32:36  klamer
+  Changes to keep Visual C++ (vc98) silent while compiling.
+
+  Revision 1.5  2005/02/28 17:21:12  klamer
+  Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+  Change use of (libg++) String to ANSI C++ string.
+
+ * Revision 1.8  1993/01/28  15:25:47  klamer
+ * Changed scaxis: now is scaled along the axis; the line-mirror behaviour
+ * is now deleted.
+ *
+ * Revision 1.7  1993/01/18  16:28:54  klamer
+ * added inclusion of err.h.
+ * Added return value to mm_add3
+ * Simplified v_norm3
+ * Changed prjorthaxis3. Tricky -- check for results.
+ * Deleted unused variables in prjpersaxis.
+ *
+ * Revision 1.6  1992/03/26  16:33:05  klamer
+ * prjpersaxis corrected for Z_AXIS (implemented proper).
+ *
+ * Revision 1.5  1992/03/25  15:13:41  klamer
+ * made lint complain less.
+ *
+ * Revision 1.4  1992/01/29  16:19:41  aartjan
+ * bugs in rot3() and vv_inprod3() fixed
+ *
+ * Revision 1.3  1992/01/29  08:45:21  aartjan
+ * sv_mul bug fixed; vv_inprod optimized
+ *
+
+  graphmat.c - 3d graphics and associated matrix and vector
+               routines in homogeneous coordinates.
+   Author : Hans Gringhuis
+*/
+
+#include	<error.h>
+
+#include <graphmat.h>
+
+static int default_gm_error ();
+/***** initialisation of general error-routine ******/
+int (*gm_error) () = default_gm_error;
+
+
+/****** General error-routine ******/
+static int
+default_gm_error (gm_errno, gm_func)
+     gm_error_t gm_errno;
+     char *gm_func;
+{
+  switch (gm_errno)
+    {
+    case NOMEM:
+      error (1, 0,
+	     "Graphmat-error : Memory allocation failure in function : %s",
+	     gm_func);
+    case DIV0:
+      error (1, 0, "Graphmat-error : Division by zero in function : %s",
+	     gm_func);
+    case MATSING:
+      error (1, 0, "Graphmat-error : Matrix is singular in function : %s",
+	     gm_func);
+    default:
+      error (1, 0, "Graphmat-error : Undefined error in function : %s",
+	     gm_func);
+    };
+  return 0;			/*UNUSED, keep Visual C++ silent */
+}
+
+/****** Level 2 : Data initialisation ******/
+hmat2_t *
+m_cpy2 (m_source, m_result)
+     const hmat2_t *m_source;
+     hmat2_t *m_result;
+{
+
+  m_result = gm_ALLOC (hmat2_t, m_result, "m_cpy2()");
+
+  *m_result = *m_source;
+
+  return m_result;
+}
+
+
+hmat2_t *
+m_unity2 (m_result)
+     hmat2_t *m_result;
+{
+  int i, j;
+
+  m_result = gm_ALLOC (hmat2_t, m_result, "m_unity2()");
+
+  for (i = 0; i < 3; i++)
+    for (j = 0; j < 3; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : 1.0;
+
+  return m_result;
+}
+
+
+hvec2_t *
+v_cpy2 (v_source, v_result)
+     const hvec2_t *v_source;
+     hvec2_t *v_result;
+{
+  v_result = gm_ALLOC (hvec2_t, v_result, "v_cpy2");
+
+  *v_result = *v_source;
+
+  return v_result;
+}
+
+
+hvec2_t *
+v_fill2 (x, y, w, v_result)
+     double x, y, w;
+     hvec2_t *v_result;
+{
+  v_result = gm_ALLOC (hvec2_t, v_result, "v_fill2()");
+
+  v_x (*v_result) = x;
+  v_y (*v_result) = y;
+  v_w (*v_result) = w;
+
+  return v_result;
+}
+
+
+hvec2_t *
+v_unity2 (axis, v_result)
+     b_axis axis;
+     hvec2_t *v_result;
+{
+  v_result = gm_ALLOC (hvec2_t, v_result, "v_unity2()");
+
+  if (axis == X_AXIS)
+    {
+      v_x (*v_result) = 1.0;
+      v_y (*v_result) = 0.0;
+    }
+  else
+    {
+      v_x (*v_result) = 0.0;
+      v_y (*v_result) = 1.0;
+    };
+  v_w (*v_result) = 1.0;
+
+  return v_result;
+}
+
+hvec2_t *
+v_zero2 (v_result)
+     hvec2_t *v_result;
+{
+  v_result = gm_ALLOC (hvec2_t, v_result, "v_zero2()");
+
+  v_x (*v_result) = v_y (*v_result) = 0.0;
+  v_w (*v_result) = 1.0;
+
+  return v_result;
+}
+
+
+hmat3_t *
+m_cpy3 (m_source, m_result)
+     const hmat3_t *m_source;
+     hmat3_t *m_result;
+{
+  m_result = gm_ALLOC (hmat3_t, m_result, "m_cpy3()");
+
+  *m_result = *m_source;
+
+  return m_result;
+}
+
+
+hmat3_t *
+m_unity3 (m_result)
+     hmat3_t *m_result;
+{
+  int i, j;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "m_unity3()");
+
+  for (i = 0; i < 4; i++)
+    for (j = 0; j < 4; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : 1.0;
+
+  return m_result;
+}
+
+
+hvec3_t *
+v_cpy3 (v_source, v_result)
+     const hvec3_t *v_source;
+     hvec3_t *v_result;
+{
+  v_result = gm_ALLOC (hvec3_t, v_result, "v_cpy3()");
+
+  *v_result = *v_source;
+
+  return v_result;
+}
+
+
+hvec3_t *
+v_fill3 (x, y, z, w, v_result)
+     double x, y, z, w;
+     hvec3_t *v_result;
+{
+  v_result = gm_ALLOC (hvec3_t, v_result, "v_fill3()");
+
+  v_x (*v_result) = x;
+  v_y (*v_result) = y;
+  v_z (*v_result) = z;
+  v_w (*v_result) = w;
+
+  return v_result;
+}
+
+
+hvec3_t *
+v_unity3 (axis, v_result)
+     b_axis axis;
+     hvec3_t *v_result;
+{
+  v_result = gm_ALLOC (hvec3_t, v_result, "v_unity3()");
+
+  switch (axis)
+    {
+    case X_AXIS:
+      v_x (*v_result) = 1.0;
+      v_y (*v_result) = v_z (*v_result) = 0.0;
+      break;
+    case Y_AXIS:
+      v_y (*v_result) = 1.0;
+      v_x (*v_result) = v_z (*v_result) = 0.0;
+      break;
+    default:
+      v_z (*v_result) = 1.0;
+      v_x (*v_result) = v_y (*v_result) = 0.0;
+      break;
+    };
+  v_w (*v_result) = 1.0;
+
+  return v_result;
+}
+
+hvec3_t *
+v_zero3 (v_result)
+     hvec3_t *v_result;
+{
+  v_result = gm_ALLOC (hvec3_t, v_result, "v_zero3()");
+
+  v_x (*v_result) = v_y (*v_result) = v_z (*v_result) = 0.0;
+  v_w (*v_result) = 1.0;
+
+  return v_result;
+}
+
+
+/****** Level 3 : Basic lineair algebra : 2D homogeneous coordinates ******/
+double
+m_det2 (matrix)
+     const hmat2_t *matrix;
+{
+
+  return
+    m_elem (*matrix, 0, 0) * (m_elem (*matrix, 1, 1) *
+			      m_elem (*matrix, 2, 2) -
+			      m_elem (*matrix, 1, 2) * m_elem (*matrix, 2,
+							       1)) -
+    m_elem (*matrix, 1,
+	    0) * (m_elem (*matrix, 0, 1) * m_elem (*matrix, 2,
+						   2) - m_elem (*matrix, 0,
+								2) *
+		  m_elem (*matrix, 2, 1)) + m_elem (*matrix, 2,
+						    0) * (m_elem (*matrix, 0,
+								  1) *
+							  m_elem (*matrix, 1,
+								  2) -
+							  m_elem (*matrix, 0,
+								  2) *
+							  m_elem (*matrix, 1,
+								  1));
+
+}
+
+double
+v_len2 (vector)
+     const hvec2_t *vector;
+{
+  double length = hypot (v_x (*vector), v_y (*vector));
+  double w = v_w (*vector);
+
+  if (w != 0)
+    return length / w;
+  else
+    return length;
+}
+
+
+double
+vtmv_mul2 (vector, matrix)
+     const hvec2_t *vector;
+     const hmat2_t *matrix;
+{
+
+  return
+    ((v_x (*vector) * m_elem (*matrix, 0, 0) +
+      v_y (*vector) * m_elem (*matrix, 1, 0) +
+      v_w (*vector) * m_elem (*matrix, 2, 0)) *
+     v_x (*vector)) +
+    ((v_x (*vector) * m_elem (*matrix, 0, 1) +
+      v_y (*vector) * m_elem (*matrix, 1, 1) +
+      v_w (*vector) * m_elem (*matrix, 2, 1)) *
+     v_y (*vector)) +
+    ((v_x (*vector) * m_elem (*matrix, 0, 2) +
+      v_y (*vector) * m_elem (*matrix, 1, 2) +
+      v_w (*vector) * m_elem (*matrix, 2, 2)) * v_w (*vector));
+}
+
+
+
+double
+vv_inprod2 (vectorA, vectorB)
+     const hvec2_t *vectorA;
+     const hvec2_t *vectorB;
+{
+  double result, div;
+
+  result = v_x (*vectorA) * v_x (*vectorB) + v_y (*vectorA) * v_y (*vectorB);
+  div = 1.0;
+  if (v_w (*vectorA) != 0.0 && v_w (*vectorA) != 1.0)
+    div *= v_w (*vectorA);
+  if (v_w (*vectorB) != 0.0 && v_w (*vectorB) != 1.0)
+    div *= v_w (*vectorB);
+  if (div != 1.0)
+    return result / div;
+
+  return result;
+}
+
+/* Used by "m_inv2()" */
+static void
+submultiples2 (m_input, m_result, rownr, workingrow)
+     hmat2_t *m_input, *m_result;
+     int rownr, workingrow;
+{
+  int i;
+  double subtractionfactor;
+
+  if ((subtractionfactor = m_elem (*m_input, workingrow, rownr)) != 0.0)
+    {
+      for (i = rownr; i < 3; i++)
+	m_elem (*m_input, workingrow, i) -=
+	  m_elem (*m_input, rownr, i) * subtractionfactor;
+
+      for (i = 0; i < 3; i++)
+	m_elem (*m_result, workingrow, i) -=
+	  m_elem (*m_result, rownr, i) * subtractionfactor;
+    };
+}
+
+/* Used by "m_inv2()" */
+static void
+interchangerow2 (m_input, m_result, rownr)
+     hmat2_t *m_input, *m_result;
+     int rownr;
+{
+  int nextelement = rownr + 1, i;
+  double buffer;
+
+  while (m_elem (*m_input, nextelement, rownr) == 0.0)
+    if (++nextelement == 3)
+      gm_error (MATSING, "m_inv2()");
+
+  /* interchange one rowelement with an element of */
+  /* a row with a nonzeroentry in the same column */
+  for (i = 0; i < 3; i++)
+    {
+      buffer = m_elem (*m_input, nextelement, i);
+      m_elem (*m_input, nextelement, i) = m_elem (*m_input, rownr, i);
+      m_elem (*m_input, rownr, i) = buffer;
+
+      buffer = m_elem (*m_result, nextelement, i);
+      m_elem (*m_result, nextelement, i) = m_elem (*m_result, rownr, i);
+      m_elem (*m_result, rownr, i) = buffer;
+    };
+}
+
+/* Used by m_inv2()" */
+static void
+reduce_row2 (m_input, m_result, rownr)
+     hmat2_t *m_input, *m_result;
+     int rownr;
+{
+  int i;
+  double factor;
+
+  if (m_elem (*m_input, rownr, rownr) == 0.0)
+    /* interchange this row with another row to
+       bring a nonzero entry in the main diagonal */
+    interchangerow2 (m_input, m_result, rownr);
+
+  /* introduce a leading one by dividing the whole row */
+  factor = m_elem (*m_input, rownr, rownr);
+  for (i = rownr; i < 3; i++)
+    m_elem (*m_input, rownr, i) /= factor;
+  for (i = 0; i < 3; i++)
+    m_elem (*m_result, rownr, i) /= factor;
+
+
+  for (i = 0; i < 3; i++)
+    if (i != rownr)
+      /* subtract suitable multiples of this row to the other rows */
+      /* so that all other entries in this column become zeros.  */
+      submultiples2 (m_input, m_result, rownr, i);
+}
+
+
+/******
+   Based on invmatrix.c, project ESPRIT 612 by Th. Koster.
+******/
+hmat2_t *
+m_inv2 (matrix, m_result)
+     const hmat2_t *matrix;
+     hmat2_t *m_result;
+{
+  hmat2_t m_input;
+  int i, j;
+
+  m_result = gm_ALLOC (hmat2_t, m_result, "m_inv2()");
+
+  for (i = 0; i < 3; i++)
+    for (j = 0; j < 3; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : 1.0;
+
+  /* save contence of matrix */
+  m_input = *matrix;
+
+  /* reduce row for row to transform the */
+  /* input matrix to an elementary matrix */
+  for (i = 0; i < 3; i++)
+    /* reduce this row to a row of an elementary matrix */
+    reduce_row2 (&m_input, m_result, i);
+
+  return m_result;
+}
+
+hmat2_t *
+m_tra2 (matrix, m_result)
+     const hmat2_t *matrix;
+     hmat2_t *m_result;
+{
+  m_result = gm_ALLOC (hmat2_t, m_result, "m_tra2()");
+
+  if (m_result != matrix)
+    {
+      int i, j;
+
+      for (i = 0; i < 3; i++)
+	for (j = 0; j < 3; j++)
+	  m_elem (*m_result, i, j) = m_elem (*matrix, j, i);
+    }
+  else
+    {
+      double buf[3];
+
+      buf[0] = m_elem (*matrix, 1, 0);
+      buf[1] = m_elem (*matrix, 2, 0);
+      buf[2] = m_elem (*matrix, 2, 1);
+
+      m_elem (*m_result, 1, 0) = m_elem (*matrix, 0, 1);
+      m_elem (*m_result, 2, 0) = m_elem (*matrix, 0, 2);
+      m_elem (*m_result, 2, 1) = m_elem (*matrix, 1, 2);
+
+      m_elem (*m_result, 0, 1) = buf[0];
+      m_elem (*m_result, 0, 2) = buf[1];
+      m_elem (*m_result, 1, 2) = buf[2];
+
+    };
+
+  return m_result;
+}
+
+
+hmat2_t *
+mm_add2 (matrixA, matrixB, m_result)
+     const hmat2_t *matrixA;
+     const hmat2_t *matrixB;
+     hmat2_t *m_result;
+{
+  int row, col;
+
+  m_result = gm_ALLOC (hmat2_t, m_result, "mm_add2()");
+
+  for (row = 0; row < 3; row++)
+    for (col = 0; col < 3; col++)
+      m_elem (*m_result, row, col) =
+	m_elem (*matrixA, row, col) + m_elem (*matrixB, row, col);
+
+  return m_result;
+}
+
+
+hmat2_t *
+mm_mul2 (matrixA, matrixB, m_result)
+     const hmat2_t *matrixA;
+     const hmat2_t *matrixB;
+     hmat2_t *m_result;
+{
+  int row, col, which_matrix;	/* Is m_result used in place \
+				   and if which matrix equals \
+				   m_result */
+  hmat2_t buf;
+
+  if (m_result == matrixA)
+    {
+      m_result = &buf;
+      which_matrix = 1;
+    }
+  else if (m_result == matrixB)
+    {
+      m_result = &buf;
+      which_matrix = 2;
+    }
+  else
+    {
+      m_result = gm_ALLOC (hmat2_t, m_result, "mm_mul2()");
+      which_matrix = 0;
+    };
+
+  for (row = 0; row < 3; row++)
+    for (col = 0; col < 3; col++)
+      m_elem (*m_result, row, col) =
+	m_elem (*matrixA, row, 0) * m_elem (*matrixB, 0,
+					    col) + m_elem (*matrixA, row,
+							   1) *
+	m_elem (*matrixB, 1, col) + m_elem (*matrixA, row,
+					    2) * m_elem (*matrixB, 2, col);
+
+  switch (which_matrix)
+    {
+    case 0:
+      return m_result;
+    case 1:			/* m_cpy2(m_result, matrixA); */
+      *(hmat2_t *) matrixA = *m_result;
+      return (hmat2_t *) matrixA;
+    case 2:			/* m_cpy2(m_result, matrixB); */
+      *(hmat2_t *) matrixB = *m_result;
+      return (hmat2_t *) matrixB;
+    };
+  error_at_line (0, 0, __FILE__, __LINE__, "This should not happen!");
+  return m_result;		/* garbage... */
+}
+
+
+hmat2_t *
+mm_sub2 (matrixA, matrixB, m_result)
+     const hmat2_t *matrixA;
+     const hmat2_t *matrixB;
+     hmat2_t *m_result;
+{
+  int row, col;
+
+  m_result = gm_ALLOC (hmat2_t, m_result, "mm_sub2()");
+
+  for (row = 0; row < 3; row++)
+    for (col = 0; col < 3; col++)
+      m_elem (*m_result, row, col) =
+	m_elem (*matrixA, row, col) - m_elem (*matrixB, row, col);
+
+  return m_result;
+}
+
+
+hmat2_t *
+mtmm_mul2 (matrixA, matrixB, m_result)
+     const hmat2_t *matrixA;
+     const hmat2_t *matrixB;
+     hmat2_t *m_result;
+{
+  hmat2_t help;
+
+  m_result = gm_ALLOC (hmat2_t, m_result, "mtmm_mul2()");
+
+  m_tra2 (matrixA, &help);
+
+  mm_mul2 (&help, matrixB, &help);
+  mm_mul2 (&help, matrixA, m_result);
+
+  return m_result;
+}
+
+
+hmat2_t *
+sm_mul2 (scalar, matrix, m_result)
+     double scalar;
+     const hmat2_t *matrix;
+     hmat2_t *m_result;
+{
+  int row, col;
+
+  m_result = gm_ALLOC (hmat2_t, m_result, "sm_mul2()");
+
+  for (row = 0; row < 3; row++)
+    for (col = 0; col < 3; col++)
+      m_elem (*m_result, row, col) = scalar * m_elem (*matrix, row, col);
+
+  return m_result;
+}
+
+
+hmat2_t *
+vvt_mul2 (vectorA, vectorB, m_result)
+     const hvec2_t *vectorA;
+     const hvec2_t *vectorB;
+     hmat2_t *m_result;
+{
+  int row, col;
+
+  m_result = gm_ALLOC (hmat2_t, m_result, "vvt_mul2()");
+
+  for (row = 0; row < 3; row++)
+    for (col = 0; col < 3; col++)
+      m_elem (*m_result, row, col) =
+	v_elem (*vectorA, row) * v_elem (*vectorB, col);
+
+  return m_result;
+}
+
+hvec2_t *
+mv_mul2 (matrix, vector, v_result)
+     const hmat2_t *matrix;
+     const hvec2_t *vector;
+     hvec2_t *v_result;
+{
+  int row, inplace;
+  hvec2_t buf;
+
+  if (v_result == vector)
+    {
+      v_result = &buf;
+      inplace = 1;
+    }
+  else
+    {
+      v_result = gm_ALLOC (hvec2_t, v_result, "mv_mul2()");
+      inplace = 0;
+    };
+
+  for (row = 0; row < 3; row++)
+    v_elem (*v_result, row) = m_elem (*matrix, row, 0) * v_elem (*vector, 0) +
+      m_elem (*matrix, row, 1) * v_elem (*vector, 1) +
+      m_elem (*matrix, row, 2) * v_elem (*vector, 2);
+
+  if (inplace)
+    {
+      /* v_cpy2(v_result, vector); */
+      *(hvec2_t *) vector = *v_result;
+
+      return (hvec2_t *) vector;
+    };
+
+  return v_result;
+}
+
+
+hvec2_t *
+sv_mul2 (scalar, vector, v_result)
+     double scalar;
+     const hvec2_t *vector;
+     hvec2_t *v_result;
+{
+  v_result = gm_ALLOC (hvec2_t, v_result, "sv_mul2()");
+
+  v_x (*v_result) = v_x (*vector) * scalar;
+  v_y (*v_result) = v_y (*vector) * scalar;
+  v_w (*v_result) = v_w (*vector);
+
+  return v_result;
+}
+
+hvec2_t *
+v_homo2 (vector, v_result)
+     const hvec2_t *vector;
+     hvec2_t *v_result;
+{
+  v_result = gm_ALLOC (hvec2_t, v_result, "v_homo2()");
+
+  v_x (*v_result) = gm_DIV (v_x (*vector), v_w (*vector), "v_homo2()");
+  v_y (*v_result) = v_y (*vector) / v_w (*vector);
+  v_w (*v_result) = 1.0;
+
+  return v_result;
+}
+
+hvec2_t *
+v_norm2 (vector, v_result)
+     const hvec2_t *vector;
+     hvec2_t *v_result;
+{
+  double length = hypot (v_x (*vector), v_y (*vector));
+
+  v_result = gm_ALLOC (hvec2_t, v_result, "v_norm2()");
+
+  v_x (*v_result) = gm_DIV (v_x (*vector), length, "v_norm2()");
+  v_y (*v_result) = v_y (*vector) / length;
+  v_w (*v_result) = v_w (*vector) / length;
+
+  return v_result;
+}
+
+
+hvec2_t *
+vv_add2 (vectorA, vectorB, v_result)
+     const hvec2_t *vectorA;
+     const hvec2_t *vectorB;
+     hvec2_t *v_result;
+{
+  v_result = gm_ALLOC (hvec2_t, v_result, "vv_add2()");
+
+  v_x (*v_result) = v_x (*vectorA) + v_x (*vectorB);
+  v_y (*v_result) = v_y (*vectorA) + v_y (*vectorB);
+  v_w (*v_result) = v_w (*vectorA) + v_w (*vectorB);
+
+  return v_result;
+}
+
+
+hvec2_t *
+vv_sub2 (vectorA, vectorB, v_result)
+     const hvec2_t *vectorA;
+     const hvec2_t *vectorB;
+     hvec2_t *v_result;
+{
+  v_result = gm_ALLOC (hvec2_t, v_result, "vv_sub2()");
+
+  v_x (*v_result) = v_x (*vectorA) - v_x (*vectorB);
+  v_y (*v_result) = v_y (*vectorA) - v_y (*vectorB);
+  v_w (*v_result) = v_w (*vectorA) - v_w (*vectorB);
+
+
+  return v_result;
+}
+
+
+/****** Level 3 : Basic lineair algebra : 3D homogeneous
+coordinates ******/
+
+/***** Function is optimized, see below !!!
+double
+m_det3(matrix)
+const hmat3_t *matrix;
+{
+   hmat2_t det2;
+   double  result=0.0;
+   int col, count, row, row_det2, factor=1.0;
+
+   for(count=0; count<4; count++)
+   {
+     row_det2 = 0;
+     for(row=0; row<4; row++)
+        if(count != row)
+        {
+          for(col=1; col<4; col++)
+             m_elem(det2, row_det2, col-1) = m_elem(*matrix, row, col);
+          row_det2++;
+        };
+     result += m_elem(*matrix, count, 0) * m_det2(&det2) * factor;
+     factor = -factor;
+   };
+   return  result;
+}
+*/
+
+/* used by m_det3() */
+/* return the under-determinant of a 4*4 matrix */
+static double
+det2_dyn (matrix, row_not)
+     const hmat3_t *matrix;
+     int row_not;
+{
+  int row[3], count, help = 0;
+
+  for (count = 0; count < 4; count++)
+    if (count != row_not)
+      row[help++] = count;
+
+  return
+    m_elem (*matrix, row[0], 1) * (m_elem (*matrix, row[1], 2) *
+				   m_elem (*matrix, row[2], 3) -
+				   m_elem (*matrix, row[1],
+					   3) * m_elem (*matrix, row[2],
+							2)) - m_elem (*matrix,
+								      row[1],
+								      1) *
+    (m_elem (*matrix, row[0], 2) * m_elem (*matrix, row[2], 3) -
+     m_elem (*matrix, row[0], 3) * m_elem (*matrix, row[2],
+					   2)) + m_elem (*matrix, row[2],
+							 1) *
+    (m_elem (*matrix, row[0], 2) * m_elem (*matrix, row[1], 3) -
+     m_elem (*matrix, row[0], 3) * m_elem (*matrix, row[1], 2));
+}
+
+double
+m_det3 (matrix)
+     const hmat3_t *matrix;
+{
+  double result = 0.0;
+  int row, factor = -1;
+
+  for (row = 0; row < 4; row++)
+    result += m_elem (*matrix, row, 0) * det2_dyn (matrix, row) *
+      (factor *= -1);
+
+  return result;
+}
+
+double
+v_len3 (vector)
+     const hvec3_t *vector;
+{
+  double length = hypot (v_x (*vector), hypot (v_y (*vector), v_z (*vector)));
+  double w = v_w (*vector);
+
+  if (w != 0.0)
+    return length / w;
+  else
+    return length;
+}
+
+
+double
+vtmv_mul3 (vector, matrix)
+     const hvec3_t *vector;
+     const hmat3_t *matrix;
+{
+
+  return
+    ((v_x (*vector) * m_elem (*matrix, 0, 0) +
+      v_y (*vector) * m_elem (*matrix, 1, 0) +
+      v_z (*vector) * m_elem (*matrix, 2, 0) +
+      v_w (*vector) * m_elem (*matrix, 3, 0)) *
+     v_x (*vector)) +
+    ((v_x (*vector) * m_elem (*matrix, 0, 1) +
+      v_y (*vector) * m_elem (*matrix, 1, 1) +
+      v_z (*vector) * m_elem (*matrix, 2, 1) +
+      v_w (*vector) * m_elem (*matrix, 3, 1)) *
+     v_y (*vector)) +
+    ((v_x (*vector) * m_elem (*matrix, 0, 2) +
+      v_y (*vector) * m_elem (*matrix, 1, 2) +
+      v_z (*vector) * m_elem (*matrix, 2, 2) +
+      v_w (*vector) * m_elem (*matrix, 3, 2)) *
+     v_z (*vector)) +
+    ((v_x (*vector) * m_elem (*matrix, 0, 3) +
+      v_y (*vector) * m_elem (*matrix, 1, 3) +
+      v_z (*vector) * m_elem (*matrix, 2, 3) +
+      v_w (*vector) * m_elem (*matrix, 3, 3)) * v_w (*vector));
+}
+
+double
+vv_inprod3 (vectorA, vectorB)
+     const hvec3_t *vectorA;
+     const hvec3_t *vectorB;
+{
+  double result, div;
+
+  result = v_x (*vectorA) * v_x (*vectorB) +
+    v_y (*vectorA) * v_y (*vectorB) + v_z (*vectorA) * v_z (*vectorB);
+  div = 1.0;
+  if (v_w (*vectorA) != 0.0 && v_w (*vectorA) != 1.0)
+    div *= v_w (*vectorA);
+  if (v_w (*vectorB) != 0.0 && v_w (*vectorB) != 1.0)
+    div *= v_w (*vectorB);
+  if (div != 1.0)
+    return result / div;
+
+  return result;
+}
+
+
+/* Used by "m_inv3()" */
+static void
+submultiples3 (m_input, m_result, rownr, workingrow)
+     hmat3_t *m_input, *m_result;
+     int rownr, workingrow;
+{
+  int i;
+  double subtractionfactor;
+
+  if ((subtractionfactor = m_elem (*m_input, workingrow, rownr)) != 0.0)
+    {
+      for (i = rownr; i < 4; i++)
+	m_elem (*m_input, workingrow, i) -=
+	  m_elem (*m_input, rownr, i) * subtractionfactor;
+
+
+      for (i = 0; i < 4; i++)
+	m_elem (*m_result, workingrow, i) -=
+	  m_elem (*m_result, rownr, i) * subtractionfactor;
+
+    };
+}
+
+/* Used by "m_inv3()" */
+static void
+interchangerow3 (m_input, m_result, rownr)
+     hmat3_t *m_input, *m_result;
+     int rownr;
+{
+  int nextelement = rownr + 1, i;
+  double buffer;
+
+  while (m_elem (*m_input, nextelement, rownr) == 0.0)
+    if (++nextelement == 4)
+      gm_error (MATSING, "m_inv3()");
+
+  /* interchange one rowelement with an element of */
+  /* a row with a nonzeroentry in the same column */
+  for (i = 0; i < 4; i++)
+    {
+      buffer = m_elem (*m_input, nextelement, i);
+      m_elem (*m_input, nextelement, i) = m_elem (*m_input, rownr, i);
+      m_elem (*m_input, rownr, i) = buffer;
+
+      buffer = m_elem (*m_result, nextelement, i);
+      m_elem (*m_result, nextelement, i) = m_elem (*m_result, rownr, i);
+      m_elem (*m_result, rownr, i) = buffer;
+    };
+}
+
+/* Used by "m_inv3()" */
+static void
+reduce_row3 (m_input, m_result, rownr)
+     hmat3_t *m_input, *m_result;
+     int rownr;
+{
+  int i;
+  double factor;
+
+  if (m_elem (*m_input, rownr, rownr) == 0.0)
+    /* interchange this row with another row to
+       bring a nonzero entry in the main diagonal */
+    interchangerow3 (m_input, m_result, rownr);
+
+  /* introduce a leading one by dividing the whole row */
+  factor = m_elem (*m_input, rownr, rownr);
+  for (i = rownr; i < 4; i++)
+    m_elem (*m_input, rownr, i) /= factor;
+  for (i = 0; i < 4; i++)
+    m_elem (*m_result, rownr, i) /= factor;
+
+
+  for (i = 0; i < 4; i++)
+    if (i != rownr)
+      /* subtract suitable multiples of this row to the other rows */
+      /* so that all other entries in this column become zeros.  */
+      submultiples3 (m_input, m_result, rownr, i);
+}
+
+
+/******
+   Based on invmatrix.c, project ESPRIT 612 by Th. Koster.
+******/
+hmat3_t *
+m_inv3 (matrix, m_result)
+     const hmat3_t *matrix;
+     hmat3_t *m_result;
+{
+  hmat3_t m_input;
+  int i;
+
+  m_result = m_unity3 (m_result);
+
+  /* save contence of matrix */
+  m_input = *matrix;
+
+  /* reduce row for row to transform the */
+  /* input matrix to an elementary matrix */
+  for (i = 0; i < 4; i++)
+    /* reduce this row to a row of an elementary matrix */
+    reduce_row3 (&m_input, m_result, i);
+
+  return m_result;
+}
+
+hmat3_t *
+m_tra3 (matrix, m_result)
+     const hmat3_t *matrix;
+     hmat3_t *m_result;
+{
+  m_result = gm_ALLOC (hmat3_t, m_result, "m_tra3()");
+
+  if (m_result != matrix)
+    {
+      int i, j;
+
+      m_result = gm_ALLOC (hmat3_t, m_result, "m_tra3()");
+
+      for (i = 0; i < 4; i++)
+	for (j = 0; j < 4; j++)
+	  m_elem (*m_result, i, j) = m_elem (*matrix, j, i);
+    }
+  else
+    {
+      double buf[6];
+
+      buf[0] = m_elem (*matrix, 1, 0);
+      buf[1] = m_elem (*matrix, 2, 0);
+      buf[2] = m_elem (*matrix, 2, 1);
+      buf[3] = m_elem (*matrix, 3, 0);
+      buf[4] = m_elem (*matrix, 3, 1);
+      buf[5] = m_elem (*matrix, 3, 2);
+
+
+      m_elem (*m_result, 1, 0) = m_elem (*matrix, 0, 1);
+      m_elem (*m_result, 2, 0) = m_elem (*matrix, 0, 2);
+      m_elem (*m_result, 2, 1) = m_elem (*matrix, 1, 2);
+      m_elem (*m_result, 3, 0) = m_elem (*matrix, 0, 3);
+      m_elem (*m_result, 3, 1) = m_elem (*matrix, 1, 3);
+      m_elem (*m_result, 3, 2) = m_elem (*matrix, 2, 3);
+
+      m_elem (*m_result, 0, 1) = buf[0];
+      m_elem (*m_result, 0, 2) = buf[1];
+      m_elem (*m_result, 0, 3) = buf[3];
+      m_elem (*m_result, 1, 2) = buf[2];
+      m_elem (*m_result, 1, 3) = buf[4];
+      m_elem (*m_result, 2, 3) = buf[5];
+    };
+
+  return m_result;
+}
+
+
+hmat3_t *
+mm_add3 (matrixA, matrixB, m_result)
+     const hmat3_t *matrixA;
+     const hmat3_t *matrixB;
+     hmat3_t *m_result;
+{
+  int row, col;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "mm_add3()");
+
+  for (row = 0; row < 4; row++)
+    for (col = 0; col < 4; col++)
+      m_elem (*m_result, row, col) =
+	m_elem (*matrixA, row, col) + m_elem (*matrixB, row, col);
+
+  return m_result;
+}
+
+
+hmat3_t *
+mm_mul3 (matrixA, matrixB, m_result)
+     const hmat3_t *matrixA;
+     const hmat3_t *matrixB;
+     hmat3_t *m_result;
+{
+  int row, col, which_matrix;
+  hmat3_t buf;
+
+  if (m_result == matrixA)
+    {
+      m_result = &buf;
+      which_matrix = 1;
+    }
+  else if (m_result == matrixB)
+    {
+      m_result = &buf;
+      which_matrix = 2;
+    }
+  else
+    {
+      m_result = gm_ALLOC (hmat3_t, m_result, "mm_mul3()");
+      which_matrix = 0;
+    };
+
+  for (row = 0; row < 4; row++)
+    for (col = 0; col < 4; col++)
+      m_elem (*m_result, row, col) =
+	m_elem (*matrixA, row, 0) * m_elem (*matrixB, 0,
+					    col) + m_elem (*matrixA, row,
+							   1) *
+	m_elem (*matrixB, 1, col) + m_elem (*matrixA, row,
+					    2) * m_elem (*matrixB, 2,
+							 col) +
+	m_elem (*matrixA, row, 3) * m_elem (*matrixB, 3, col);
+
+  switch (which_matrix)
+    {
+    case 0:
+      return m_result;
+    case 1:			/* m_cpy3(m_result, matrixA); */
+      *(hmat3_t *) matrixA = *m_result;
+      return (hmat3_t *) matrixA;
+    case 2:			/* m_cpy3(m_result, matrixB); */
+      *(hmat3_t *) matrixB = *m_result;
+      return (hmat3_t *) matrixB;
+    };
+  error_at_line (0, 0, __FILE__, __LINE__, "This should not happen!");
+  return m_result;		/* garbage... */
+}
+
+
+hmat3_t *
+mm_sub3 (matrixA, matrixB, m_result)
+     const hmat3_t *matrixA;
+     const hmat3_t *matrixB;
+     hmat3_t *m_result;
+{
+  int row, col;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "mm_sub3()");
+
+  for (row = 0; row < 4; row++)
+    for (col = 0; col < 4; col++)
+      m_elem (*m_result, row, col) =
+	m_elem (*matrixA, row, col) - m_elem (*matrixB, row, col);
+
+  return m_result;
+}
+
+
+hmat3_t *
+mtmm_mul3 (matrixA, matrixB, m_result)
+     const hmat3_t *matrixA;
+     const hmat3_t *matrixB;
+     hmat3_t *m_result;
+{
+  hmat3_t help;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "mtmm_mul3()");
+
+  m_tra3 (matrixA, &help);
+
+  mm_mul3 (&help, matrixB, &help);
+  mm_mul3 (&help, matrixA, m_result);
+
+  return m_result;
+}
+
+
+hmat3_t *
+sm_mul3 (scalar, matrix, m_result)
+     double scalar;
+     const hmat3_t *matrix;
+     hmat3_t *m_result;
+{
+  int row, col;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "sm_mul3()");
+
+  for (row = 0; row < 4; row++)
+    for (col = 0; col < 4; col++)
+      m_elem (*m_result, row, col) = scalar * m_elem (*matrix, row, col);
+
+  return m_result;
+}
+
+
+hvec3_t *
+mv_mul3 (matrix, vector, v_result)
+     const hmat3_t *matrix;
+     const hvec3_t *vector;
+     hvec3_t *v_result;
+{
+  int row, inplace;
+  hvec3_t buf;
+
+  if (v_result == vector)
+    {
+      v_result = &buf;
+      inplace = 1;
+    }
+  else
+    {
+      v_result = gm_ALLOC (hvec3_t, v_result, "mv_mul3()");
+      inplace = 0;
+    };
+
+  for (row = 0; row < 4; row++)
+    v_elem (*v_result, row) = m_elem (*matrix, row, 0) *
+      v_elem (*vector, 0) + m_elem (*matrix, row, 1) *
+      v_elem (*vector, 1) + m_elem (*matrix, row, 2) *
+      v_elem (*vector, 2) + m_elem (*matrix, row, 3) * v_elem (*vector, 3);
+
+  if (inplace)
+    {
+      v_cpy3 (v_result, (hvec3_t *) vector);
+      return (hvec3_t *) vector;
+    };
+
+  return v_result;
+}
+
+
+hvec3_t *
+sv_mul3 (scalar, vector, v_result)
+     double scalar;
+     const hvec3_t *vector;
+     hvec3_t *v_result;
+{
+  v_result = gm_ALLOC (hvec3_t, v_result, "sv_mul3()");
+
+  v_x (*v_result) = v_x (*vector) * scalar;
+  v_y (*v_result) = v_y (*vector) * scalar;
+  v_z (*v_result) = v_z (*vector) * scalar;
+  v_w (*v_result) = v_w (*vector);
+
+  return v_result;
+}
+
+hvec3_t *
+v_homo3 (vector, v_result)
+     const hvec3_t *vector;
+     hvec3_t *v_result;
+{
+  v_result = gm_ALLOC (hvec3_t, v_result, "v_homo3()");
+
+  v_x (*v_result) = gm_DIV (v_x (*vector), v_w (*vector), "v_homo3()");
+  v_y (*v_result) = v_y (*vector) / v_w (*vector);
+  v_z (*v_result) = v_z (*vector) / v_w (*vector);
+  v_w (*v_result) = 1.0;
+
+  return v_result;
+}
+
+
+hvec3_t *
+v_norm3 (vector, v_result)
+     const hvec3_t *vector;
+     hvec3_t *v_result;
+{
+  double length = hypot (v_x (*vector), hypot (v_y (*vector), v_z (*vector)));
+
+  v_result = gm_ALLOC (hvec3_t, v_result, "v_norm3()");
+
+  v_x (*v_result) = gm_DIV (v_x (*vector), length, "v_norm2()");
+  v_y (*v_result) = v_y (*vector) / length;
+  v_z (*v_result) = v_z (*vector) / length;
+  v_w (*v_result) = v_w (*vector) / length;
+
+  return v_result;
+}
+
+hvec3_t *
+vv_add3 (vectorA, vectorB, v_result)
+     const hvec3_t *vectorA;
+     const hvec3_t *vectorB;
+     hvec3_t *v_result;
+{
+  v_result = gm_ALLOC (hvec3_t, v_result, "vv_add3()");
+
+  v_x (*v_result) = v_x (*vectorA) + v_x (*vectorB);
+  v_y (*v_result) = v_y (*vectorA) + v_y (*vectorB);
+  v_z (*v_result) = v_z (*vectorA) + v_z (*vectorB);
+  v_w (*v_result) = v_w (*vectorA) + v_w (*vectorB);
+
+  return v_result;
+}
+
+
+hvec3_t *
+vv_cross3 (vectorA, vectorB, v_result)
+     const hvec3_t *vectorA;
+     const hvec3_t *vectorB;
+     hvec3_t *v_result;
+{
+  int which_vec;		/* Is v_result used in place, if so which \
+				   vectors are equal ? */
+
+  hvec3_t buf;
+
+  if (v_result == vectorA)
+    {
+      v_result = &buf;
+      which_vec = 1;
+    }
+  else if (v_result == vectorB)
+    {
+      v_result = &buf;
+      which_vec = 2;
+    }
+  else
+    {
+      v_result = gm_ALLOC (hvec3_t, v_result, "vv_cross3()");
+      which_vec = 0;
+    };
+
+  v_x (*v_result) = v_y (*vectorA) * v_z (*vectorB) -
+    v_z (*vectorA) * v_y (*vectorB);
+  v_y (*v_result) = v_z (*vectorA) * v_x (*vectorB) -
+    v_x (*vectorA) * v_z (*vectorB);
+  v_z (*v_result) = v_x (*vectorA) * v_y (*vectorB) -
+    v_y (*vectorA) * v_x (*vectorB);
+  v_w (*v_result) = v_w (*vectorA) * v_w (*vectorB);
+
+  switch (which_vec)
+    {
+    case 0:
+      return v_result;
+    case 1:			/* v_cpy3(v_result, vectorA); */
+      *(hvec3_t *) vectorA = *v_result;
+      return (hvec3_t *) vectorA;
+    case 2:			/* v_cpy3(v_result, vectorB); */
+      *(hvec3_t *) vectorB = *v_result;
+      return (hvec3_t *) vectorB;
+    };
+  error_at_line (0, 0, __FILE__, __LINE__, "This should not happen!");
+  return v_result;		/* garbage... */
+}
+
+hvec3_t *
+vv_sub3 (vectorA, vectorB, v_result)
+     const hvec3_t *vectorA;
+     const hvec3_t *vectorB;
+     hvec3_t *v_result;
+{
+  v_result = gm_ALLOC (hvec3_t, v_result, "vv_sub3()");
+
+  v_x (*v_result) = v_x (*vectorA) - v_x (*vectorB);
+  v_y (*v_result) = v_y (*vectorA) - v_y (*vectorB);
+  v_z (*v_result) = v_z (*vectorA) - v_z (*vectorB);
+  v_w (*v_result) = v_w (*vectorA) - v_w (*vectorB);
+
+  return v_result;
+}
+
+
+hmat3_t *
+vvt_mul3 (vectorA, vectorB, m_result)
+     const hvec3_t *vectorA;
+     const hvec3_t *vectorB;
+     hmat3_t *m_result;
+{
+  int row, col;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "vvt_mul3()");
+
+  for (row = 0; row < 4; row++)
+    for (col = 0; col < 4; col++)
+      m_elem (*m_result, row, col) =
+	v_elem (*vectorA, row) * v_elem (*vectorB, col);
+
+  return m_result;
+}
+
+
+/****** Level 4 : Elementary transformations ******/
+hmat2_t *
+miraxis2 (axis, m_result)
+     b_axis axis;
+     hmat2_t *m_result;
+{
+  int i, j;
+
+  m_result = gm_ALLOC (hmat2_t, m_result, "miraxis2()");
+
+  for (i = 0; i < 3; i++)
+    for (j = 0; j < 3; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : 1.0;
+
+  if (axis == X_AXIS)
+    m_elem (*m_result, 1, 1) = -1.0;
+  else
+    m_elem (*m_result, 0, 0) = -1.0;
+
+  return m_result;
+}
+
+
+hmat2_t *
+mirorig2 (m_result)
+     hmat2_t *m_result;
+{
+  int i, j;
+
+  m_result = gm_ALLOC (hmat2_t, m_result, "mirorig()");
+
+  for (i = 0; i < 3; i++)
+    for (j = 0; j < 3; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : -1.0;
+
+  m_elem (*m_result, 2, 2) = 1.0;
+
+  return m_result;
+}
+
+hmat2_t *
+rot2 (rotation, m_result)
+     double rotation;
+     hmat2_t *m_result;
+{
+  m_result = gm_ALLOC (hmat2_t, m_result, "rot2()");
+
+  m_elem (*m_result, 0, 0) = m_elem (*m_result, 1, 1) = cos (rotation);
+  m_elem (*m_result, 1, 0) = sin (rotation);
+  m_elem (*m_result, 0, 1) = -m_elem (*m_result, 1, 0);
+
+  m_elem (*m_result, 2, 0) = m_elem (*m_result, 2, 1) =
+    m_elem (*m_result, 0, 2) = m_elem (*m_result, 1, 2) = 0.0;
+  m_elem (*m_result, 2, 2) = 1.0;
+
+  return m_result;
+}
+
+
+hmat2_t *
+scaorig2 (scale, m_result)
+     double scale;
+     hmat2_t *m_result;
+{
+  int i, j;
+
+  m_result = gm_ALLOC (hmat2_t, m_result, "scaorig2()");
+
+  for (i = 0; i < 3; i++)
+    for (j = 0; j < 3; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : scale;
+
+  m_elem (*m_result, 2, 2) = 1.0;
+
+  return m_result;
+}
+
+
+hmat2_t *
+scaxis2 (scale, axis, m_result)
+     double scale;
+     b_axis axis;
+     hmat2_t *m_result;
+{
+#ifdef notdef
+  int i, j;
+
+  m_result = gm_ALLOC (hmat2_t, m_result, "miraxis2()");
+
+  for (i = 0; i < 3; i++)
+    for (j = 0; j < 3; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : scale;
+#else
+  m_result = m_unity2 (m_result);
+#endif
+
+  if (axis == X_AXIS)
+    m_elem (*m_result, 1, 1) = scale;
+  else
+    m_elem (*m_result, 0, 0) = scale;
+
+  return m_result;
+}
+
+
+hmat2_t *
+transl2 (translation, m_result)
+     const hvec2_t *translation;
+     hmat2_t *m_result;
+{
+  int i, j;
+
+  m_result = gm_ALLOC (hmat2_t, m_result, "transl2()");
+
+  for (i = 0; i < 3; i++)
+    for (j = 0; j < 2; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : 1.0;
+
+  m_elem (*m_result, 0, 2) = v_x (*translation);
+  m_elem (*m_result, 1, 2) = v_y (*translation);
+  m_elem (*m_result, 2, 2) = 1.0;
+
+  return m_result;
+}
+
+
+hmat3_t *
+miraxis3 (axis, m_result)
+     b_axis axis;
+     hmat3_t *m_result;
+{
+  int i, j;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "miraxis3()");
+
+  for (i = 0; i < 4; i++)
+    for (j = 0; j < 4; j++)
+      m_elem (*m_result, i, j) =
+	(i != j) ? 0.0 : (i != (int) axis) ? 1.0 : -1.0;
+
+  m_elem (*m_result, 3, 3) = 1.0;
+
+  return m_result;
+}
+
+
+hmat3_t *
+mirorig3 (m_result)
+     hmat3_t *m_result;
+{
+  int i, j;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "mirorig3()");
+
+  for (i = 0; i < 4; i++)
+    for (j = 0; j < 4; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : -1.0;
+
+  m_elem (*m_result, 3, 3) = 1.0;
+
+  return m_result;
+}
+
+hmat3_t *
+mirplane3 (plane, m_result)
+     b_axis plane;
+     hmat3_t *m_result;
+{
+  int i, j;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "mirplane3()");
+  for (i = 0; i < 4; i++)
+    for (j = 0; j < 4; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : 1.0;
+
+  m_elem (*m_result, (int) plane, (int) plane) = -1.0;
+
+  return m_result;
+}
+
+
+hmat3_t *
+prjorthaxis (axis, m_result)
+     b_axis axis;
+     hmat3_t *m_result;
+{
+#ifndef notdef
+  /* An orthographic projection, handled similar to a perspective
+   * projection, is a unity operator!
+   * So the coordinate of the axis over which is projected is the
+   * distance from the projection plane to the input vector
+   */
+  m_result = m_unity3 (m_result);
+#else /* notdef */
+  int i, j;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "prjorthaxis()");
+
+  for (i = 0; i < 4; i++)
+    for (j = 0; j < 4; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : 1.0;
+
+  m_elem (*m_result, (int) axis, (int) axis) = 0.0;
+#endif /* notdef */
+
+  return m_result;
+}
+
+
+hmat3_t *
+prjpersaxis (axis, m_result)
+     b_axis axis;
+     hmat3_t *m_result;
+{
+#ifdef notdef
+  hvec3_t x, y, z, viewdir;
+  int i;
+#endif
+
+  m_result = m_unity3 (m_result);
+
+  m_elem (*m_result, 3, 3) = 0.0;
+
+  switch (axis)
+    {
+    case X_AXIS:
+      m_elem (*m_result, 3, 0) = 1.0;
+      break;
+    case Y_AXIS:
+      m_elem (*m_result, 3, 1) = 1.0;
+      break;
+    case Z_AXIS:
+      m_elem (*m_result, 3, 2) = 1.0;
+      break;
+    };
+
+  return m_result;
+}
+
+
+
+hmat3_t *
+rot3 (rotation, axis, m_result)
+     double rotation;
+     b_axis axis;
+     hmat3_t *m_result;
+{
+  int i, j;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "rot3()");
+
+  for (i = 0; i < 4; i++)
+    for (j = 0; j < 4; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : 1.0;
+
+  i = ((int) axis + 1) % 3;
+  j = ((int) axis + 2) % 3;
+  m_elem (*m_result, i, i) = m_elem (*m_result, j, j) = cos (rotation);
+  m_elem (*m_result, j, i) = sin (rotation);
+  m_elem (*m_result, i, j) = -m_elem (*m_result, j, i);
+
+  return m_result;
+}
+
+hmat3_t *
+scaorig3 (scale, m_result)
+     double scale;
+     hmat3_t *m_result;
+{
+  int i, j;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "scaorig2()");
+
+  for (i = 0; i < 4; i++)
+    for (j = 0; j < 4; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : scale;
+
+  m_elem (*m_result, 3, 3) = 1.0;
+
+  return m_result;
+}
+
+
+hmat3_t *
+scaplane3 (scale, plane, m_result)
+     double scale;
+     b_axis plane;
+     hmat3_t *m_result;
+{
+  int i, j;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "scaplane3()");
+  for (i = 0; i < 4; i++)
+    for (j = 0; j < 4; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : 1.0;
+
+  m_elem (*m_result, (int) plane, (int) plane) = scale;
+
+  return m_result;
+}
+
+
+hmat3_t *
+scaxis3 (scale, axis, m_result)
+     double scale;
+     b_axis axis;
+     hmat3_t *m_result;
+{
+#ifdef notdef
+  int i, j;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "scaxis3()");
+
+  for (i = 0; i < 4; i++)
+    for (j = 0; j < 4; j++)
+      m_elem (*m_result, i, j) =
+	(i != j) ? 0.0 : (i != (int) axis) ? -1.0 : scale;
+
+  m_elem (*m_result, 3, 3) = 1.0;
+#else
+  m_result = m_unity3 (m_result);
+
+  m_elem (*m_result, axis, axis) = scale;
+#endif
+
+  return m_result;
+}
+
+
+hmat3_t *
+transl3 (translation, m_result)
+     const hvec3_t *translation;
+     hmat3_t *m_result;
+{
+  int i, j;
+
+  m_result = gm_ALLOC (hmat3_t, m_result, "transl2()");
+
+  for (i = 0; i < 4; i++)
+    for (j = 0; j < 3; j++)
+      m_elem (*m_result, i, j) = (i != j) ? 0.0 : 1.0;
+
+  m_elem (*m_result, 0, 3) = v_x (*translation);
+  m_elem (*m_result, 1, 3) = v_y (*translation);
+  m_elem (*m_result, 2, 3) = v_z (*translation);
+  m_elem (*m_result, 3, 3) = 1.0;
+
+  return m_result;
+}
--- clippoly-0.11.orig/graphmat.h
+++ clippoly-0.11/graphmat.h
@@ -1,328 +1,354 @@
-/*
- *    tutvis library
-
- *    Copyright (C) 1993  University of Twente
-
- *    klamer@mi.el.utwente.nl
-
- *    This library is free software; you can redistribute it and/or
- *    modify it under the terms of the GNU Library General Public
- *    License as published by the Free Software Foundation; either
- *    version 2 of the License, or (at your option) any later version.
-
- *    This library is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *    Library General Public License for more details.
-
- *    You should have received a copy of the GNU Library General Public
- *    License along with this library; if not, write to the Free
- *    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
-	graphmat.h
-	Author: Hans Gringhuis
-
-	graphmat - 3d graphics and associated matrix and vector routines
-*/
-/*
- * $Log: graphmat.h,v $
- * Revision 1.6  2005/02/28 21:12:05  klamer
- * Made changes such that gcc 3.4.2 compiles silent with -ansi -pedantic -Wall.
- *
- * Revision 1.5  2005/02/28 17:21:12  klamer
- * Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
- * Change use of (libg++) String to ANSI C++ string.
- *
- * Revision 1.6  1992/10/16  16:16:47  klamer
- * Gave anonymous structures and unions names;
- * This to circumvent bug in gdb4.5.
- *
- * Revision 1.5  1992/09/11  15:08:09  klamer
- * deleted const on first argument of gm_alloc.
- * added const to v_len2() call.
- *
- * Revision 1.4  1992/05/19  07:41:49  klamer
- * gm_dummy is no longer defined if C++ is used.
- * C++ is more efficient now!
- *
- * Revision 1.3  1992/05/11  13:10:54  klamer
- * Added const in prototypes for const arguments.
- *
- * Revision 1.2  1992/05/07  14:48:47  klamer
- * made C++ compatible.
- *
- */
-
-#ifndef GRAPHMAT_INCLUDE
-#define GRAPHMAT_INCLUDE
-
-/****** Other includes ******/
-#ifdef __cplusplus
-#include <cstdio>
-#include <cstdlib>
-#include <cmath>
-#else
-#ifndef	FILE
-#include <stdio.h>
-#endif
-#ifndef __malloc_h
-#include <malloc.h>
-#endif
-#ifndef __math_h
-#include <math.h>
-#endif
-#endif
-
-
-/****** DEFINES ******/
-
-/* macro's for accessing the data elements of a vector or a matrix */
-#define m_elem(mat, i, j)	((mat).m[(i)][(j)])
-#define v_elem(vec, i) 		((vec).a[(int)(i)]) 
-#define v_x(vec)		((vec).s.x)
-#define v_y(vec)		((vec).s.y)
-#define v_z(vec)		((vec).s.z)
-#define v_w(vec)		((vec).s.w)
-
-/*
-#define gm_NEW(type, ptr, func)  \
-		(((gm_dummy = malloc(sizeof(type))) == NULL) ? \
-	        ((type *)gm_error(NOMEM, func)) : \
-		(type *)gm_dummy)  
-*/
-
-typedef enum
-{
-    DIV0, NOMEM, MATSING
-} gm_error_t;
-
-#ifdef __cplusplus
-extern "C" void gm_error( int, const char * );
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-inline void *
-gm_alloc( /*const*/ void *ptr, const char *func, int len )
-{
-	if (ptr != 0)
-		return ptr;
-	else
-	{
-		void	*gm_dummy;
-
-		if ((gm_dummy = malloc(len)) == NULL)
-			return gm_error(NOMEM,func), (void *)0;
-		else
-			return gm_dummy;
-	}
-}
-#define	gm_ALLOC(type, ptr, func)	((type *) \
-					  gm_alloc(ptr, func, sizeof(type))
-#else
-/****** Globals ******/
-char		*gm_dummy; /* used for memory allocation in gm_ALLOC() */
-
-/* check if ptr is NULL, if so then allocate memory else return ptr */
-#define gm_ALLOC(type, ptr, func)  (((ptr) == NULL) ? \
-		((gm_dummy = malloc(sizeof(type))) == NULL) ? \
-	        ((type *)gm_error(NOMEM, func)) : \
-		(type *)gm_dummy : (ptr)) 
-#endif
-
-/* if ptr is NULL then deallocate used space pointed by ptr */
-#define gm_FREE(ptr) if((ptr) != NULL) free((char *)(ptr))
-
-
-/* divide num by div if div != 0 else gm_error() */
-#define gm_DIV(num, div, func) (((div) != 0.0) ? ((num) / (div)) : gm_error(DIV0, (func)))
-
-
-/****** Level 1 : data definition ******/
-typedef union hvec2_t
-{
-	double a[3];
-	struct hvec2_s
-	{
-		double	x, y, w; 
-	} s;
-} hvec2_t;
-
-
-typedef union hvec3_t
-{
-	double a[4];
-	struct hvec3_s
-	{
-		double x, y, z, w;
-	} s;
-} hvec3_t;
-
-
-typedef struct hmat2_t
-{
-	double m[3][3];
-} hmat2_t;
-
-
-typedef struct hmat3_t
-{
-	double m[4][4];
-} hmat3_t;
-
-
-typedef enum
-{
-	X_AXIS, Y_AXIS, Z_AXIS
-} b_axis;
-
-
-/****** Level 2 : Data initialisation ******/
-#define m_free2(matrix)		gm_FREE(matrix)
-#define v_free2(vector)		gm_FREE(vector)
-#define m_free3(matrix)		gm_FREE(matrix)
-#define v_free3(vector)		gm_FREE(vector)
-
-#ifndef __cplusplus
-#define m_alloc2(m_result)	gm_ALLOC(hmat2_t, (m_result), "m_alloc2()")
-#define v_alloc2(v_result)	gm_ALLOC(hvec2_t, (v_result), "v_alloc2()")
-
-#define m_alloc3(m_result)	gm_ALLOC(hmat3_t, (m_result), "m_alloc3()")
-#define v_alloc3(v_result)	gm_ALLOC(hvec3_t, (v_result), "v_alloc3()")
-#else
-inline void *
-Alloc(unsigned int x )
-{
-	void	*res;
-
-	res = malloc(x);
-	if (res == 0)
-		gm_error(NOMEM,"Alloc");
-
-	return res;
-}
-
-
-inline hmat2_t *
-m_alloc2(hmat2_t *r)
-{
-	if (r)
-		return r;
-	else
-		return (hmat2_t *) Alloc(sizeof(hmat2_t));
-}
-
-inline hmat3_t *
-m_alloc3(hmat3_t *r)
-{
-	if (r)
-		return r;
-	else
-		return (hmat3_t *) Alloc(sizeof(hmat3_t));
-}
-
-inline hvec2_t *
-v_alloc2(hvec2_t *r)
-{
-	if (r)
-		return r;
-	else
-		return (hvec2_t *) Alloc(sizeof(hvec2_t));
-}
-
-inline hvec3_t *
-v_alloc3(hvec3_t *r)
-{
-	if (r)
-		return r;
-	else
-		return (hvec3_t *) Alloc(sizeof(hvec3_t));
-}
-#endif
-
-/****** FUNCTION DEFINITIONS ******/
-#if defined(__STDC__) || defined(__cplusplus)
-# define P_(s) s
-#else
-# define P_(s) ()
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#define	C__	}
-#else
-#define	C__
-#endif
-
-hmat2_t *m_cpy2 P_((const hmat2_t *m_source, hmat2_t *m_result));
-hmat2_t *m_unity2 P_((hmat2_t *m_result));
-hvec2_t *v_cpy2 P_((const hvec2_t *v_source, hvec2_t *v_result));
-hvec2_t *v_fill2 P_((double x, double y, double w, hvec2_t *v_result));
-hvec2_t *v_unity2 P_((b_axis axis, hvec2_t *v_result));
-hvec2_t *v_zero2 P_((hvec2_t *v_result));
-hmat3_t *m_cpy3 P_((const hmat3_t *m_source, hmat3_t *m_result));
-hmat3_t *m_unity3 P_((hmat3_t *m_result));
-hvec3_t *v_cpy3 P_((const hvec3_t *v_source, hvec3_t *v_result));
-hvec3_t *v_fill3 P_((double x, double y, double z, double w, hvec3_t *v_result));
-hvec3_t *v_unity3 P_((b_axis axis, hvec3_t *v_result));
-hvec3_t *v_zero3 P_((hvec3_t *v_result));
-double m_det2 P_((const hmat2_t *matrix));
-double v_len2 P_((const hvec2_t *vector));
-double vtmv_mul2 P_((const hvec2_t *vector, const hmat2_t *matrix));
-double vv_inprod2 P_((const hvec2_t *vectorA, const hvec2_t *vectorB));
-hmat2_t *m_inv2 P_((const hmat2_t *matrix, hmat2_t *m_result));
-hmat2_t *m_tra2 P_((const hmat2_t *matrix, hmat2_t *m_result));
-hmat2_t *mm_add2 P_((const hmat2_t *matrixA, const hmat2_t *matrixB, hmat2_t *m_result));
-hmat2_t *mm_mul2 P_((const hmat2_t *matrixA, const hmat2_t *matrixB, hmat2_t *m_result));
-hmat2_t *mm_sub2 P_((const hmat2_t *matrixA, const hmat2_t *matrixB, hmat2_t *m_result));
-hmat2_t *mtmm_mul2 P_((const hmat2_t *matrixA, const hmat2_t *matrixB, hmat2_t *m_result));
-hmat2_t *sm_mul2 P_((double scalar, const hmat2_t *matrix, hmat2_t *m_result));
-hmat2_t *vvt_mul2 P_((const hvec2_t *vectorA, const hvec2_t *vectorB, hmat2_t *m_result));
-hvec2_t *mv_mul2 P_((const hmat2_t *matrix, const hvec2_t *vector, hvec2_t *v_result));
-hvec2_t *sv_mul2 P_((double scalar, const hvec2_t *vector, hvec2_t *v_result));
-hvec2_t *v_homo2 P_((const hvec2_t *vector, hvec2_t *v_result));
-hvec2_t *v_norm2 P_((const hvec2_t *vector, hvec2_t *v_result));
-hvec2_t *vv_add2 P_((const hvec2_t *vectorA, const hvec2_t *vectorB, hvec2_t *v_result));
-hvec2_t *vv_sub2 P_((const hvec2_t *vectorA, const hvec2_t *vectorB, hvec2_t *v_result));
-double m_det3 P_((const hmat3_t *matrix));
-double v_len3 P_((const hvec3_t *vector));
-double vtmv_mul3 P_((const hvec3_t *vector, const hmat3_t *matrix));
-double vv_inprod3 P_((const hvec3_t *vectorA, const hvec3_t *vectorB));
-hmat3_t *m_inv3 P_((const hmat3_t *matrix, hmat3_t *m_result));
-hmat3_t *m_tra3 P_((const hmat3_t *matrix, hmat3_t *m_result));
-hmat3_t *mm_add3 P_((const hmat3_t *matrixA, const hmat3_t *matrixB, hmat3_t *m_result));
-hmat3_t *mm_mul3 P_((const hmat3_t *matrixA, const hmat3_t *matrixB, hmat3_t *m_result));
-hmat3_t *mm_sub3 P_((const hmat3_t *matrixA, const hmat3_t *matrixB, hmat3_t *m_result));
-hmat3_t *mtmm_mul3 P_((const hmat3_t *matrixA, const hmat3_t *matrixB, hmat3_t *m_result));
-hmat3_t *sm_mul3 P_((double scalar, const hmat3_t *matrix, hmat3_t *m_result));
-hvec3_t *mv_mul3 P_((const hmat3_t *matrix, const hvec3_t *vector, hvec3_t *v_result));
-hvec3_t *sv_mul3 P_((double scalar, const hvec3_t *vector, hvec3_t *v_result));
-hvec3_t *v_homo3 P_((const hvec3_t *vector, hvec3_t *v_result));
-hvec3_t *v_norm3 P_((const hvec3_t *vector, hvec3_t *v_result));
-hvec3_t *vv_add3 P_((const hvec3_t *vectorA, const hvec3_t *vectorB, hvec3_t *v_result));
-hvec3_t *vv_cross3 P_((const hvec3_t *vectorA, const hvec3_t *vectorB, hvec3_t *v_result));
-hvec3_t *vv_sub3 P_((const hvec3_t *vectorA, const hvec3_t *vectorB, hvec3_t *v_result));
-hmat3_t *vvt_mul3 P_((const hvec3_t *vectorA, const hvec3_t *vectorB, hmat3_t *m_result));
-hmat2_t *miraxis2 P_((b_axis axis, hmat2_t *m_result));
-hmat2_t *mirorig2 P_((hmat2_t *m_result));
-hmat2_t *rot2 P_((double rotation, hmat2_t *m_result));
-hmat2_t *scaorig2 P_((double scale, hmat2_t *m_result));
-hmat2_t *scaxis2 P_((double scale, b_axis axis, hmat2_t *m_result));
-hmat2_t *transl2 P_((const hvec2_t *translation, hmat2_t *m_result));
-hmat3_t *miraxis3 P_((b_axis axis, hmat3_t *m_result));
-hmat3_t *mirorig3 P_((hmat3_t *m_result));
-hmat3_t *mirplane3 P_((b_axis plane, hmat3_t *m_result));
-hmat3_t *prjorthaxis P_((b_axis axis, hmat3_t *m_result));
-hmat3_t *prjpersaxis P_((b_axis axis, hmat3_t *m_result));
-hmat3_t *rot3 P_((double rotation, b_axis axis, hmat3_t *m_result));
-hmat3_t *scaorig3 P_((double scale, hmat3_t *m_result));
-hmat3_t *scaplane3 P_((double scale, b_axis plane, hmat3_t *m_result));
-hmat3_t *scaxis3 P_((double scale, b_axis axis, hmat3_t *m_result));
-hmat3_t *transl3 P_((const hvec3_t *translation, hmat3_t *m_result));
-
-C__
-#undef C__
-#undef P_
-#endif
+/*
+ *    tutvis library
+
+ *    Copyright (C) 1993  University of Twente
+
+ *    klamer@mi.el.utwente.nl
+
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Library General Public
+ *    License as published by the Free Software Foundation; either
+ *    version 2 of the License, or (at your option) any later version.
+
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Library General Public License for more details.
+
+ *    You should have received a copy of the GNU Library General Public
+ *    License along with this library; if not, write to the Free
+ *    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+	graphmat.h
+	Author: Hans Gringhuis
+
+	graphmat - 3d graphics and associated matrix and vector routines
+*/
+/*
+ * Revision 1.7  2005/03/12 16:32:36  klamer
+ * Changes to keep Visual C++ (vc98) silent while compiling.
+ *
+ * Revision 1.6  2005/02/28 21:12:05  klamer
+ * Made changes such that gcc 3.4.2 compiles silent with -ansi -pedantic -Wall.
+ *
+ * Revision 1.5  2005/02/28 17:21:12  klamer
+ * Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+ * Change use of (libg++) String to ANSI C++ string.
+ *
+ * Revision 1.6  1992/10/16  16:16:47  klamer
+ * Gave anonymous structures and unions names;
+ * This to circumvent bug in gdb4.5.
+ *
+ * Revision 1.5  1992/09/11  15:08:09  klamer
+ * deleted const on first argument of gm_alloc.
+ * added const to v_len2() call.
+ *
+ * Revision 1.4  1992/05/19  07:41:49  klamer
+ * gm_dummy is no longer defined if C++ is used.
+ * C++ is more efficient now!
+ *
+ * Revision 1.3  1992/05/11  13:10:54  klamer
+ * Added const in prototypes for const arguments.
+ *
+ * Revision 1.2  1992/05/07  14:48:47  klamer
+ * made C++ compatible.
+ *
+ */
+
+#ifndef GRAPHMAT_INCLUDE
+#define GRAPHMAT_INCLUDE
+
+/****** Other includes ******/
+#ifdef __cplusplus
+#include <cstdio>
+#include <cstdlib>
+#include <cmath>
+#else
+#ifndef	FILE
+#include <stdio.h>
+#endif
+#ifndef __malloc_h
+#include <malloc.h>
+#endif
+#ifndef __math_h
+#include <math.h>
+#endif
+#endif
+
+
+/****** DEFINES ******/
+
+/* macro's for accessing the data elements of a vector or a matrix */
+#define m_elem(mat, i, j)	((mat).m[(i)][(j)])
+#define v_elem(vec, i) 		((vec).a[(int)(i)])
+#define v_x(vec)		((vec).s.x)
+#define v_y(vec)		((vec).s.y)
+#define v_z(vec)		((vec).s.z)
+#define v_w(vec)		((vec).s.w)
+
+/*
+#define gm_NEW(type, ptr, func)  \
+		(((gm_dummy = malloc(sizeof(type))) == NULL) ? \
+	        ((type *)gm_error(NOMEM, func)) : \
+		(type *)gm_dummy)
+*/
+
+typedef enum
+{
+  DIV0, NOMEM, MATSING
+} gm_error_t;
+
+#ifdef __cplusplus
+extern "C" void gm_error (int, const char *);
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+inline void *
+gm_alloc ( /*const */ void *ptr, const char *func, int len)
+{
+  if (ptr != 0)
+    return ptr;
+  else
+    {
+      void *gm_dummy;
+
+      if ((gm_dummy = malloc (len)) == NULL)
+	return gm_error (NOMEM, func), (void *) 0;
+      else
+	return gm_dummy;
+    }
+}
+
+#define	gm_ALLOC(type, ptr, func)	((type *) \
+					  gm_alloc(ptr, func, sizeof(type))
+#else
+/****** Globals ******/
+char *gm_dummy;			/* used for memory allocation in gm_ALLOC() */
+
+/* check if ptr is NULL, if so then allocate memory else return ptr */
+#define gm_ALLOC(type, ptr, func)  (((ptr) == NULL) ? \
+		((gm_dummy = (char *)malloc(sizeof(type))) == NULL) ? \
+	        (gm_error(NOMEM, func), (type *)NULL) : \
+		(type *)gm_dummy : (ptr))
+#endif
+
+/* if ptr is NULL then deallocate used space pointed by ptr */
+#define gm_FREE(ptr) if((ptr) != NULL) free((char *)(ptr))
+
+
+/* divide num by div if div != 0 else gm_error() */
+#define gm_DIV(num, div, func) (((div) != 0.0) ? ((num) / (div)) : gm_error(DIV0, (func)))
+
+
+/****** Level 1 : data definition ******/
+typedef union hvec2_t
+{
+  double a[3];
+  struct hvec2_s
+  {
+    double x, y, w;
+  } s;
+} hvec2_t;
+
+
+typedef union hvec3_t
+{
+  double a[4];
+  struct hvec3_s
+  {
+    double x, y, z, w;
+  } s;
+} hvec3_t;
+
+
+typedef struct hmat2_t
+{
+  double m[3][3];
+} hmat2_t;
+
+
+typedef struct hmat3_t
+{
+  double m[4][4];
+} hmat3_t;
+
+
+typedef enum
+{
+  X_AXIS, Y_AXIS, Z_AXIS
+} b_axis;
+
+
+/****** Level 2 : Data initialisation ******/
+#define m_free2(matrix)		gm_FREE(matrix)
+#define v_free2(vector)		gm_FREE(vector)
+#define m_free3(matrix)		gm_FREE(matrix)
+#define v_free3(vector)		gm_FREE(vector)
+
+#ifndef __cplusplus
+#define m_alloc2(m_result)	gm_ALLOC(hmat2_t, (m_result), "m_alloc2()")
+#define v_alloc2(v_result)	gm_ALLOC(hvec2_t, (v_result), "v_alloc2()")
+
+#define m_alloc3(m_result)	gm_ALLOC(hmat3_t, (m_result), "m_alloc3()")
+#define v_alloc3(v_result)	gm_ALLOC(hvec3_t, (v_result), "v_alloc3()")
+#else
+inline void *
+Alloc (unsigned int x)
+{
+  void *res;
+
+  res = malloc (x);
+  if (res == 0)
+    gm_error (NOMEM, "Alloc");
+
+  return res;
+}
+
+
+inline hmat2_t *
+m_alloc2 (hmat2_t *r)
+{
+  if (r)
+    return r;
+  else
+    return (hmat2_t *) Alloc (sizeof (hmat2_t));
+}
+
+inline hmat3_t *
+m_alloc3 (hmat3_t *r)
+{
+  if (r)
+    return r;
+  else
+    return (hmat3_t *) Alloc (sizeof (hmat3_t));
+}
+
+inline hvec2_t *
+v_alloc2 (hvec2_t *r)
+{
+  if (r)
+    return r;
+  else
+    return (hvec2_t *) Alloc (sizeof (hvec2_t));
+}
+
+inline hvec3_t *
+v_alloc3 (hvec3_t *r)
+{
+  if (r)
+    return r;
+  else
+    return (hvec3_t *) Alloc (sizeof (hvec3_t));
+}
+#endif
+
+/****** FUNCTION DEFINITIONS ******/
+#if defined(__STDC__) || defined(__cplusplus)
+#define P_(s) s
+#else
+#define P_(s) ()
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#define	C__	}
+#else
+#define	C__
+#endif
+
+hmat2_t *m_cpy2 P_ ((const hmat2_t * m_source, hmat2_t * m_result));
+hmat2_t *m_unity2 P_ ((hmat2_t * m_result));
+hvec2_t *v_cpy2 P_ ((const hvec2_t * v_source, hvec2_t * v_result));
+hvec2_t *v_fill2 P_ ((double x, double y, double w, hvec2_t * v_result));
+hvec2_t *v_unity2 P_ ((b_axis axis, hvec2_t * v_result));
+hvec2_t *v_zero2 P_ ((hvec2_t * v_result));
+hmat3_t *m_cpy3 P_ ((const hmat3_t * m_source, hmat3_t * m_result));
+hmat3_t *m_unity3 P_ ((hmat3_t * m_result));
+hvec3_t *v_cpy3 P_ ((const hvec3_t * v_source, hvec3_t * v_result));
+hvec3_t *v_fill3
+P_ ((double x, double y, double z, double w, hvec3_t * v_result));
+hvec3_t *v_unity3 P_ ((b_axis axis, hvec3_t * v_result));
+hvec3_t *v_zero3 P_ ((hvec3_t * v_result));
+double m_det2 P_ ((const hmat2_t * matrix));
+double v_len2 P_ ((const hvec2_t * vector));
+double vtmv_mul2 P_ ((const hvec2_t * vector, const hmat2_t * matrix));
+double vv_inprod2 P_ ((const hvec2_t * vectorA, const hvec2_t * vectorB));
+hmat2_t *m_inv2 P_ ((const hmat2_t * matrix, hmat2_t * m_result));
+hmat2_t *m_tra2 P_ ((const hmat2_t * matrix, hmat2_t * m_result));
+hmat2_t *mm_add2
+P_ ((const hmat2_t * matrixA, const hmat2_t * matrixB, hmat2_t * m_result));
+hmat2_t *mm_mul2
+P_ ((const hmat2_t * matrixA, const hmat2_t * matrixB, hmat2_t * m_result));
+hmat2_t *mm_sub2
+P_ ((const hmat2_t * matrixA, const hmat2_t * matrixB, hmat2_t * m_result));
+hmat2_t *mtmm_mul2
+P_ ((const hmat2_t * matrixA, const hmat2_t * matrixB, hmat2_t * m_result));
+hmat2_t *sm_mul2
+P_ ((double scalar, const hmat2_t * matrix, hmat2_t * m_result));
+hmat2_t *vvt_mul2
+P_ ((const hvec2_t * vectorA, const hvec2_t * vectorB, hmat2_t * m_result));
+hvec2_t *mv_mul2
+P_ ((const hmat2_t * matrix, const hvec2_t * vector, hvec2_t * v_result));
+hvec2_t *sv_mul2
+P_ ((double scalar, const hvec2_t * vector, hvec2_t * v_result));
+hvec2_t *v_homo2 P_ ((const hvec2_t * vector, hvec2_t * v_result));
+hvec2_t *v_norm2 P_ ((const hvec2_t * vector, hvec2_t * v_result));
+hvec2_t *vv_add2
+P_ ((const hvec2_t * vectorA, const hvec2_t * vectorB, hvec2_t * v_result));
+hvec2_t *vv_sub2
+P_ ((const hvec2_t * vectorA, const hvec2_t * vectorB, hvec2_t * v_result));
+double m_det3 P_ ((const hmat3_t * matrix));
+double v_len3 P_ ((const hvec3_t * vector));
+double vtmv_mul3 P_ ((const hvec3_t * vector, const hmat3_t * matrix));
+double vv_inprod3 P_ ((const hvec3_t * vectorA, const hvec3_t * vectorB));
+hmat3_t *m_inv3 P_ ((const hmat3_t * matrix, hmat3_t * m_result));
+hmat3_t *m_tra3 P_ ((const hmat3_t * matrix, hmat3_t * m_result));
+hmat3_t *mm_add3
+P_ ((const hmat3_t * matrixA, const hmat3_t * matrixB, hmat3_t * m_result));
+hmat3_t *mm_mul3
+P_ ((const hmat3_t * matrixA, const hmat3_t * matrixB, hmat3_t * m_result));
+hmat3_t *mm_sub3
+P_ ((const hmat3_t * matrixA, const hmat3_t * matrixB, hmat3_t * m_result));
+hmat3_t *mtmm_mul3
+P_ ((const hmat3_t * matrixA, const hmat3_t * matrixB, hmat3_t * m_result));
+hmat3_t *sm_mul3
+P_ ((double scalar, const hmat3_t * matrix, hmat3_t * m_result));
+hvec3_t *mv_mul3
+P_ ((const hmat3_t * matrix, const hvec3_t * vector, hvec3_t * v_result));
+hvec3_t *sv_mul3
+P_ ((double scalar, const hvec3_t * vector, hvec3_t * v_result));
+hvec3_t *v_homo3 P_ ((const hvec3_t * vector, hvec3_t * v_result));
+hvec3_t *v_norm3 P_ ((const hvec3_t * vector, hvec3_t * v_result));
+hvec3_t *vv_add3
+P_ ((const hvec3_t * vectorA, const hvec3_t * vectorB, hvec3_t * v_result));
+hvec3_t *vv_cross3
+P_ ((const hvec3_t * vectorA, const hvec3_t * vectorB, hvec3_t * v_result));
+hvec3_t *vv_sub3
+P_ ((const hvec3_t * vectorA, const hvec3_t * vectorB, hvec3_t * v_result));
+hmat3_t *vvt_mul3
+P_ ((const hvec3_t * vectorA, const hvec3_t * vectorB, hmat3_t * m_result));
+hmat2_t *miraxis2 P_ ((b_axis axis, hmat2_t * m_result));
+hmat2_t *mirorig2 P_ ((hmat2_t * m_result));
+hmat2_t *rot2 P_ ((double rotation, hmat2_t * m_result));
+hmat2_t *scaorig2 P_ ((double scale, hmat2_t * m_result));
+hmat2_t *scaxis2 P_ ((double scale, b_axis axis, hmat2_t * m_result));
+hmat2_t *transl2 P_ ((const hvec2_t * translation, hmat2_t * m_result));
+hmat3_t *miraxis3 P_ ((b_axis axis, hmat3_t * m_result));
+hmat3_t *mirorig3 P_ ((hmat3_t * m_result));
+hmat3_t *mirplane3 P_ ((b_axis plane, hmat3_t * m_result));
+hmat3_t *prjorthaxis P_ ((b_axis axis, hmat3_t * m_result));
+hmat3_t *prjpersaxis P_ ((b_axis axis, hmat3_t * m_result));
+hmat3_t *rot3 P_ ((double rotation, b_axis axis, hmat3_t * m_result));
+hmat3_t *scaorig3 P_ ((double scale, hmat3_t * m_result));
+hmat3_t *scaplane3 P_ ((double scale, b_axis plane, hmat3_t * m_result));
+hmat3_t *scaxis3 P_ ((double scale, b_axis axis, hmat3_t * m_result));
+hmat3_t *transl3 P_ ((const hvec3_t * translation, hmat3_t * m_result));
+
+C__
+#undef C__
+#undef P_
+#endif
--- clippoly-0.11.orig/in_file
+++ clippoly-0.11/in_file
@@ -1,8 +1,8 @@
-1 -1
-0 1
-2 1
-PolyMagic
-0 0
-1 2
-2 0
-PolyMagic
+1 -1
+0 1
+2 1
+PolyMagic
+0 0
+1 2
+2 0
+PolyMagic
--- clippoly-0.11.orig/in_file.test
+++ clippoly-0.11/in_file.test
@@ -1,13 +1,13 @@
-0.043677       0.0036737
-0.0490363       -0.0524051
-0.00302704      -0.0568021
--0.00233231     -0.000723313
-PolyMagic
-0.043677   0.0036737
-0.0213455       0.00153953
-0.0180227       0.00206061
-0.0237406       0.0385219
-0.0850047       0.0289144
-0.0792868       -0.00754689
-0.0442238       -0.00204827
-PolyMagic
+0.043677       0.0036737
+0.0490363       -0.0524051
+0.00302704      -0.0568021
+-0.00233231     -0.000723313
+PolyMagic
+0.043677   0.0036737
+0.0213455       0.00153953
+0.0180227       0.00206061
+0.0237406       0.0385219
+0.0850047       0.0289144
+0.0792868       -0.00754689
+0.0442238       -0.00204827
+PolyMagic
--- clippoly-0.11.orig/in_file.wrong
+++ clippoly-0.11/in_file.wrong
@@ -1,8 +1,8 @@
-1 -1
-2 1
-0 1
-PolyMagic
-0 0
-2 0
-1 2
-PolyMagic
+1 -1
+2 1
+0 1
+PolyMagic
+0 0
+2 0
+1 2
+PolyMagic
--- clippoly-0.11.orig/lgpl.texinfo
+++ clippoly-0.11/lgpl.texinfo
@@ -1,542 +1,542 @@
-@ifset lgpl-appendix
-@appendix GNU LIBRARY GENERAL PUBLIC LICENSE
-@end ifset
-@ifclear lgpl-appendix
-@unnumbered GNU LIBRARY GENERAL PUBLIC LICENSE
-@end ifclear
-@center Version 2, June 1991
-
-@display
-Copyright @copyright{} 1991 Free Software Foundation, Inc.
-675 Mass Ave, Cambridge, MA 02139, USA
-Everyone is permitted to copy and distribute verbatim copies
-of this license document, but changing it is not allowed.
-
-[This is the first released version of the library GPL.  It is
- numbered 2 because it goes with version 2 of the ordinary GPL.]
-@end display
-
-@unnumberedsec Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software---to make sure the software is free for all its users.
-
-  This license, the Library General Public License, applies to some
-specially designated Free Software Foundation software, and to any
-other libraries whose authors decide to use it.  You can use it for
-your libraries, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if
-you distribute copies of the library, or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link a program with the library, you must provide
-complete object files to the recipients so that they can relink them
-with the library, after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  Our method of protecting your rights has two steps: (1) copyright
-the library, and (2) offer you this license which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  Also, for each distributor's protection, we want to make certain
-that everyone understands that there is no warranty for this free
-library.  If the library is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original
-version, so that any problems introduced by others will not reflect on
-the original authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that companies distributing free
-software will individually obtain patent licenses, thus in effect
-transforming the program into proprietary software.  To prevent this,
-we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
-  Most GNU software, including some libraries, is covered by the ordinary
-GNU General Public License, which was designed for utility programs.  This
-license, the GNU Library General Public License, applies to certain
-designated libraries.  This license is quite different from the ordinary
-one; be sure to read it in full, and don't assume that anything in it is
-the same as in the ordinary license.
-
-  The reason we have a separate public license for some libraries is that
-they blur the distinction we usually make between modifying or adding to a
-program and simply using it.  Linking a program with a library, without
-changing the library, is in some sense simply using the library, and is
-analogous to running a utility program or application program.  However, in
-a textual and legal sense, the linked executable is a combined work, a
-derivative of the original library, and the ordinary General Public License
-treats it as such.
-
-  Because of this blurred distinction, using the ordinary General
-Public License for libraries did not effectively promote software
-sharing, because most developers did not use the libraries.  We
-concluded that weaker conditions might promote sharing better.
-
-  However, unrestricted linking of non-free programs would deprive the
-users of those programs of all benefit from the free status of the
-libraries themselves.  This Library General Public License is intended to
-permit developers of non-free programs to use free libraries, while
-preserving your freedom as a user of such programs to change the free
-libraries that are incorporated in them.  (We have not seen how to achieve
-this as regards changes in header files, but we have achieved it as regards
-changes in the actual functions of the Library.)  The hope is that this
-will lead to faster development of free libraries.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-``work based on the library'' and a ``work that uses the library''.  The
-former contains code derived from the library, while the latter only
-works together with the library.
-
-  Note that it is possible for a library to be covered by the ordinary
-General Public License rather than by this special one.
-
-@iftex
-@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-@end iftex
-@ifinfo
-@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-@end ifinfo
-
-@enumerate
-@item
-This License Agreement applies to any software library which
-contains a notice placed by the copyright holder or other authorized
-party saying it may be distributed under the terms of this Library
-General Public License (also called ``this License'').  Each licensee is
-addressed as ``you''.
-
-  A ``library'' means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The ``Library'', below, refers to any such software library or work
-which has been distributed under these terms.  A ``work based on the
-Library'' means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term ``modification''.)
-
-  ``Source code'' for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-@item
-You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-@item
-You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-@enumerate
-@item
-The modified work must itself be a software library.
-
-@item
-You must cause the files modified to carry prominent notices
-stating that you changed the files and the date of any change.
-
-@item
-You must cause the whole of the work to be licensed at no
-charge to all third parties under the terms of this License.
-
-@item
-If a facility in the modified Library refers to a function or a
-table of data to be supplied by an application program that uses
-the facility, other than as an argument passed when the facility
-is invoked, then you must make a good faith effort to ensure that,
-in the event an application does not supply such function or
-table, the facility still operates, and performs whatever part of
-its purpose remains meaningful.
-
-(For example, a function in a library to compute square roots has
-a purpose that is entirely well-defined independent of the
-application.  Therefore, Subsection 2d requires that any
-application-supplied function or table used by this function must
-be optional: if the application does not supply it, the square
-root function must still compute square roots.)
-@end enumerate
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-@item
-You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-@item
-You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-@item
-A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a ``work that uses the Library''.  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a ``work that uses the Library'' with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a ``work that uses the
-library''.  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a ``work that uses the Library'' uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-@item
-As an exception to the Sections above, you may also compile or
-link a ``work that uses the Library'' with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-@enumerate
-@item
-Accompany the work with the complete corresponding
-machine-readable source code for the Library including whatever
-changes were used in the work (which must be distributed under
-Sections 1 and 2 above); and, if the work is an executable linked
-with the Library, with the complete machine-readable ``work that
-uses the Library'', as object code and/or source code, so that the
-user can modify the Library and then relink to produce a modified
-executable containing the modified Library.  (It is understood
-that the user who changes the contents of definitions files in the
-Library will not necessarily be able to recompile the application
-to use the modified definitions.)
-
-@item
-Accompany the work with a written offer, valid for at
-least three years, to give the same user the materials
-specified in Subsection 6a, above, for a charge no more
-than the cost of performing this distribution.
-
-@item
-If distribution of the work is made by offering access to copy
-from a designated place, offer equivalent access to copy the above
-specified materials from the same place.
-
-@item
-Verify that the user has already received a copy of these
-materials or that you have already sent this user a copy.
-@end enumerate
-
-  For an executable, the required form of the ``work that uses the
-Library'' must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the source code distributed need not include anything that is normally
-distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-@item
-You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-@enumerate
-@item
-Accompany the combined library with a copy of the same work
-based on the Library, uncombined with any other library
-facilities.  This must be distributed under the terms of the
-Sections above.
-
-@item
-Give prominent notice with the combined library of the fact
-that part of it is a work based on the Library, and explaining
-where to find the accompanying uncombined form of the same work.
-@end enumerate
-
-@item
-You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-@item
-You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-@item
-Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-@item
-If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-@item
-If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-@item
-The Free Software Foundation may publish revised and/or new
-versions of the Library General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-``any later version'', you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-@item
-If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-@iftex
-@heading NO WARRANTY
-@end iftex
-@ifinfo
-@center NO WARRANTY
-@end ifinfo
-
-@item
-BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY ``AS IS'' WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-@item
-IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-@end enumerate
-
-@iftex
-@heading END OF TERMS AND CONDITIONS
-@end iftex
-@ifinfo
-@center END OF TERMS AND CONDITIONS
-@end ifinfo
-
-@page
-@unnumberedsec How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-``copyright'' line and a pointer to where the full notice is found.
-
-@smallexample
-@var{one line to give the library's name and a brief idea of what it does.}
-Copyright (C) @var{year}  @var{name of author}
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with this library; if not, write to the Free
-Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-@end smallexample
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a ``copyright disclaimer'' for the library, if
-necessary.  Here is a sample; alter the names:
-
-@example
-Yoyodyne, Inc., hereby disclaims all copyright interest in the
-library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-@var{signature of Ty Coon}, 1 April 1990
-Ty Coon, President of Vice
-@end example
-
-That's all there is to it!
+@ifset lgpl-appendix
+@appendix GNU LIBRARY GENERAL PUBLIC LICENSE
+@end ifset
+@ifclear lgpl-appendix
+@unnumbered GNU LIBRARY GENERAL PUBLIC LICENSE
+@end ifclear
+@center Version 2, June 1991
+
+@display
+Copyright @copyright{} 1991 Free Software Foundation, Inc.
+675 Mass Ave, Cambridge, MA 02139, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+@end display
+
+@unnumberedsec Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software---to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+``work based on the library'' and a ``work that uses the library''.  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+@iftex
+@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end iftex
+@ifinfo
+@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end ifinfo
+
+@enumerate
+@item
+This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called ``this License'').  Each licensee is
+addressed as ``you''.
+
+  A ``library'' means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The ``Library'', below, refers to any such software library or work
+which has been distributed under these terms.  A ``work based on the
+Library'' means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term ``modification''.)
+
+  ``Source code'' for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+@item
+You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+@item
+You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+@enumerate
+@item
+The modified work must itself be a software library.
+
+@item
+You must cause the files modified to carry prominent notices
+stating that you changed the files and the date of any change.
+
+@item
+You must cause the whole of the work to be licensed at no
+charge to all third parties under the terms of this License.
+
+@item
+If a facility in the modified Library refers to a function or a
+table of data to be supplied by an application program that uses
+the facility, other than as an argument passed when the facility
+is invoked, then you must make a good faith effort to ensure that,
+in the event an application does not supply such function or
+table, the facility still operates, and performs whatever part of
+its purpose remains meaningful.
+
+(For example, a function in a library to compute square roots has
+a purpose that is entirely well-defined independent of the
+application.  Therefore, Subsection 2d requires that any
+application-supplied function or table used by this function must
+be optional: if the application does not supply it, the square
+root function must still compute square roots.)
+@end enumerate
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+@item
+You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+@item
+You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+@item
+A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a ``work that uses the Library''.  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a ``work that uses the Library'' with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a ``work that uses the
+library''.  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a ``work that uses the Library'' uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+@item
+As an exception to the Sections above, you may also compile or
+link a ``work that uses the Library'' with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+@enumerate
+@item
+Accompany the work with the complete corresponding
+machine-readable source code for the Library including whatever
+changes were used in the work (which must be distributed under
+Sections 1 and 2 above); and, if the work is an executable linked
+with the Library, with the complete machine-readable ``work that
+uses the Library'', as object code and/or source code, so that the
+user can modify the Library and then relink to produce a modified
+executable containing the modified Library.  (It is understood
+that the user who changes the contents of definitions files in the
+Library will not necessarily be able to recompile the application
+to use the modified definitions.)
+
+@item
+Accompany the work with a written offer, valid for at
+least three years, to give the same user the materials
+specified in Subsection 6a, above, for a charge no more
+than the cost of performing this distribution.
+
+@item
+If distribution of the work is made by offering access to copy
+from a designated place, offer equivalent access to copy the above
+specified materials from the same place.
+
+@item
+Verify that the user has already received a copy of these
+materials or that you have already sent this user a copy.
+@end enumerate
+
+  For an executable, the required form of the ``work that uses the
+Library'' must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+@item
+You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+@enumerate
+@item
+Accompany the combined library with a copy of the same work
+based on the Library, uncombined with any other library
+facilities.  This must be distributed under the terms of the
+Sections above.
+
+@item
+Give prominent notice with the combined library of the fact
+that part of it is a work based on the Library, and explaining
+where to find the accompanying uncombined form of the same work.
+@end enumerate
+
+@item
+You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+@item
+You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+@item
+Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+@item
+If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+@item
+If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+@item
+The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+``any later version'', you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+@item
+If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+@iftex
+@heading NO WARRANTY
+@end iftex
+@ifinfo
+@center NO WARRANTY
+@end ifinfo
+
+@item
+BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY ``AS IS'' WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+@item
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+@end enumerate
+
+@iftex
+@heading END OF TERMS AND CONDITIONS
+@end iftex
+@ifinfo
+@center END OF TERMS AND CONDITIONS
+@end ifinfo
+
+@page
+@unnumberedsec How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+``copyright'' line and a pointer to where the full notice is found.
+
+@smallexample
+@var{one line to give the library's name and a brief idea of what it does.}
+Copyright (C) @var{year}  @var{name of author}
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free
+Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+@end smallexample
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a ``copyright disclaimer'' for the library, if
+necessary.  Here is a sample; alter the names:
+
+@example
+Yoyodyne, Inc., hereby disclaims all copyright interest in the
+library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+@var{signature of Ty Coon}, 1 April 1990
+Ty Coon, President of Vice
+@end example
+
+That's all there is to it!
--- clippoly-0.11.orig/nclip.cc
+++ clippoly-0.11/nclip.cc
@@ -1,673 +1,681 @@
-static const char rcs_id[] = "$Header: /cvsroot/clippoly/clippoly/nclip.cc,v 1.5 2005/02/28 17:21:12 klamer Exp $";
-
-//    nclip: a polygon clip library
-
-//    Copyright (C) 1993  University of Twente
-
-//    klamer@mi.el.utwente.nl
-
-//    This library is free software; you can redistribute it and/or
-//    modify it under the terms of the GNU Library General Public
-//    License as published by the Free Software Foundation; either
-//    version 2 of the License, or (at your option) any later version.
-
-//    This library is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//    Library General Public License for more details.
-
-//    You should have received a copy of the GNU Library General Public
-//    License along with this library; if not, write to the Free
-//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-// $Log: nclip.cc,v $
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.2  1994/01/04  12:55:37  klamer
-// Added DEBUG_NCLIP support.
-// Make intersect call itself again if the polygons change.
-// New function label_shared2, called from label_shared.
-// Major changes in label_shared.
-// Make_poly depends on inproducts now rather than on angles.
-// Make sure starting polygons are clockwise oriented.
-//
-// Revision 1.1  1992/12/07  10:46:35  klamer
-// Initial revision
-//
-
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
-#include	<assert.h>
-
-#include	<graphmat.h>
-#include	<graphadd.h>
-#include        <err.h>
-
-#include	<malloc.h>
-
-#include	<poly.h>
-#include	<primitives.h>
-#include	<posadder.h>
-#include	"nclip.h"
-
-#ifdef DEBUG1
-#include	<iostream.h>
-#include	<poly_io.h>
-#endif
-#ifdef DEBUG_NCLIP
-#include        "poly_io.h"
-#include        <iostream.h>
-#include        <fstream.h>
-#include        <iomanip.h>
-static ofstream	db("debugnc");
-#endif
-
-static const char h_rcs_id[] = NCLIP_H;
-
-// Intersect Edge a & b, and return the intersection point in p1 and p2.
-// The return value means the number of intersections. Two intersections
-// mean that a and b are on the same line, the intersection points are in that
-// case the extrema of the joint line segment
-int		
-  intersect( const Edge &a, const Edge &b, Point &p1, Point &p2 )
-{
-  hvec2_t	s1, s2;
-  
-  int ret = v_inters2( a.p1().hvec(), a.p2().hvec(), b.p1().hvec(), b.p2().hvec(), &s1, &s2 );
-  
-  switch(ret)
-    {case 2:
-      p2 = s2;
-      // Fall Through
-  case 1:
-    p1 = s1;
-  }
-  
-    return ret;
-}
-
-// calculate all the intersections between a and b. Add the intersection points
-// to a and b.
-// returns total number of intersections found.
-int
-  intersect( Poly &a, Poly &b )
-{
-  PolyIter	a_iter( a );
-  int			res = 0, res2 = 0;
-  
-  while( a_iter() )
-    {
-      PolyIter	b_iter( b );
-      
-      while( b_iter() )
-	{
-	  Point	intersect1, intersect2;
-	  int		cnt = intersect( a_iter.edge(), b_iter.edge(),
-					intersect1, intersect2 );
-	  res += cnt;
-	  
-	  if (cnt)
-	    {
-	      res2 += PolyIter::add_point( a_iter, b_iter, intersect1 );
-	      if (cnt >= 2)
-		{
-		  res2 += PolyIter::add_point( a_iter, b_iter, intersect2 );
-	      }
-	  }
-      }
-  }
-  
-  if (res2 != 0)
-  	return res + intersect(a,b);
-
-    return res;
-}
-
-// Check whether line p1-p2 is inside the polygon pointed by pn. p1 should equal pn.
-// if inside do a_iter.set_inside() else a_iter.set_none(), as it is outside
-void
-  label_shared2( PolyIter &pi, const Point &p1, const Point &p2, const PolyNode &pn )
-{
-  assert(p1 == pn.point());
-  
-  Point		prev = pn.prevnode().point(),
-  		next = pn.nextnode().point();
-  
-  // The *dir are direction vectors!
-  Point		cdir = p2 - p1, pdir = p1 - prev, ndir = next - p1;
-
-  int		p_c = (pdir.x() * cdir.y() - pdir.y() * cdir.x()) >= 0,
-  		n_c = (ndir.x() * cdir.y() - ndir.y() * cdir.x()) >= 0,
-  		p_n = (pdir.x() * ndir.y() - pdir.y() * ndir.x()) >= 0;
-  
-  if (p_n)	// pn points to a concave corner?
-  {
-    if (p_c && n_c)
-      pi.set_none();
-    else
-      pi.set_inside();
-  } else {
-    if (p_c || n_c)
-      pi.set_none();
-    else
-      pi.set_inside();
-  }
-}
-
-// label the edges from polygon a with respect to polygon b. possible
-// labels are: shared, inside and none. inside means that the edge is inside
-// b, none means outside, and shared means that b has the same edge.
-void
-label_shared( Poly & a, const Poly & b )
-{
-	PolyIter	a_iter( a );
-
-	while(a_iter())
-	{
-		const PolyNode *b1, *b2;
-	
-		if ((b1 = a_iter.node()->link()) && 
-					(b2 = a_iter.nextnode()->link()))
-		{
-			// Seems shared -- but check 
-			// that b1 and b2 are also connected!
-			if ((b.nextnode(b1) == b2) || (b.nextnode(b2) == b1))
-			{
-				a_iter.set_shared();
-				continue;
-			} /* else if (b.has_point( a_iter.edge().middle() ))
-				a_iter.set_inside();
-			else
-				a_iter.set_none(); */
-			//continue;
-		}
-#ifdef notdef		
-		if (b1)
-		{ 
-		  // So a_iter.node() shares a point with b
-		    if (b.has_point(a_iter.nextnode().point()))
-		      a_iter.set_inside();
-		    else
-		      a_iter.set_none();
-		} else {
-		  // The current node is not on b
-		  if (b.has_point(a_iter.node().point()))
-		    a_iter.set_inside();
-		  else
-		    a_iter.set_none();
-		}		    
-		  
-		//if (b.has_point( a_iter.edge().middle() ))
-		//	a_iter.set_inside();
-		//else
-		//	a_iter.set_none();
-#else
-		if (b1)
-		  label_shared2(a_iter, a_iter.node()->point(), a_iter.nextnode()->point(), *b1 );
-		  //warning("NYI %s %d\n", __FILE__, __LINE__);
-		else if ((b2 = a_iter.nextnode()->link()))
-		  label_shared2(a_iter, a_iter.nextnode()->point(), a_iter.node()->point(), *b2 );
-		  //warning("NYI %s %d\n", __FILE__, __LINE__);
-		else {
-		  int in1 = b.has_point(a_iter.node()->point()),
-		      in2 = b.has_point(a_iter.nextnode()->point());
-		  
-		  if (in1 != in2)
-		    error("This should not happen! %s %d\n", __FILE__, __LINE__ );
-		  if (in1)
-		    a_iter.set_inside();
-		  else
-		    a_iter.set_none();
-		}
-#endif		
-	}
-}		
-
-// In the two make_poly functions (second one below this one) a new
-// polygon is added to polylist. done contains a list of edge which
-// already are assigned to a polygon, and thus do not belong to this
-// polygon (as the directed edge a->b is only part of one clockwise
-// oriented polygon.) The second make_poly function is a recursive function
-// which finishes the work initiated in the first.
-void
-make_poly( const Point &point, 
-	DirPolyIter &follow, PolyPList &polylist, NodePEdgeList &done )
-{
-	NodePEdge	edge( follow );
-	
-	if (done.contains(edge))	// Ignore if this edge already is done.
-		return;
-		
-	// Make new polygon. start with only one point & edge
-	Poly	*new_poly = new Poly( follow.point(), &follow.poly(), 
-							follow.edgestate() );
-	
-	// finish the construction of the polygon.
-	if (make_poly( point, point, follow, done, new_poly ))
-	{
-		// We want only clockwise oriented polygons!
-		if (new_poly->orientation() != ClockWise)
-			delete new_poly;
-		else
-			polylist.add( new_poly );
-	} else // Will never happen when only one is returned...
-		delete new_poly;
-}
-
-// second part of make_poly. Continue adding points to new_poly until
-// start_point is reached, and thus the polygon is complete. follow is used
-// to get the next point of the polygon. If the next point is an intersection
-// between the two original polygons, decide whether the other polygon
-// should be followed. This is done by selecting the smallest angle.
-int 
-make_poly( const Point &start_point, const Point &point, 
-	DirPolyIter &follow, NodePEdgeList &done, Poly * new_poly )
-{
-	done.add( NodePEdge( follow ) );
-	
-	follow.next();
-
-	// if (follow.point() == start_point)
-	//	return 1;
-			
-	double	cur_angle = angle( point, follow.point(), follow.nextpoint() );
-
-	assert(cur_angle != 0);
-		
-	IterDirection	dir = NONE;
-	
-	if (follow.link())
-	{
-		double	other_angle = angle( point, follow.point(), 
-						follow.linknextpoint() );
-		Point	d1 = follow.linknextpoint() - follow.point(),
-			d2 = follow.nextpoint() - follow.point(),
-			d3 = follow.point() - point;
-		double inp = d1.x() * d2.y() - d2.x() * d1.y(),	
-			inp2 = d1.x() * d3.y() - d3.x() * d1.y();
-		int	lf = inp > 0,
-			ld = inp2 > 0,
-			df = (d3.x() * d2.y() - d2.x() * d3.y()) > 0,
-			condition = (lf + ld + df) >= 2;
-		// if (inp2 = 0)	// Similar to other_angle = 0
-		if (point == follow.linknextpoint())
-		  condition = 0;
-		assert((cur_angle != other_angle) ||
-		       (inp != 0) ||
-		       (follow.linknextpoint() == follow.nextpoint()));
-		assert((other_angle != 0) ||
-		       (inp2 != 0) ||
-		       (follow.linknextpoint() == point));
-		//assert((cur_angle == other_angle) ||
-		//       ((((cur_angle - other_angle) > 0)) 
-		//	^ condition));
-#ifdef notdef
-		if ((other_angle != 0) && (other_angle == cur_angle ?
-					   inp > 0 :
-					  other_angle < cur_angle))
-		{
-		  	assert(condition);
-#else
-		if (condition)
-		{
-#endif
-			cur_angle = other_angle;
-			dir = FORWARD;
-			d2 = d1;
-		} //else
-		  //assert(!condition);
-		
-		other_angle = angle( point, follow.point(), 
-						follow.linkprevpoint() );
-		d1 = follow.linkprevpoint() - follow.point();
-		//	d2 = follow.nextpoint() - follow.point();
-		inp = d1.x() * d2.y() - d2.x() * d1.y();
-		inp2 = d1.x() * d3.y() - d3.x() * d1.y();
-		lf = inp > 0;
-		ld = inp2 > 0;
-		df = (d3.x() * d2.y() - d2.x() * d3.y()) > 0;
-		condition = (lf + ld + df) >= 2;
-		// if (inp2 = 0)
-		if (point == follow.linkprevpoint())
-		  condition = 0;
-		assert((cur_angle != other_angle) || 
-		       (inp != 0) ||
-		       (follow.linkprevpoint() == follow.nextpoint()));
-		assert((other_angle != 0) ||
-		       (inp2 != 0) ||
-		       (follow.linkprevpoint() == point));
-		//assert((cur_angle == other_angle) ||
-		//       ((((cur_angle - other_angle) > 0))
-		//	^ condition));
-#ifdef notdef
-		if ((other_angle != 0) && (other_angle == cur_angle ?
-					   inp > 0 :
-					   other_angle < cur_angle))
-		{
-		  	assert(condition);
-#else
-		if (condition)
-		{
-#endif
-			// No need to update cur_angle
-			dir = BACKWARD;
-		} //else
-		 	// assert(!condition);
-	}
-	
-	if (dir != NONE)
-	{
-
-		DirPolyIter	next_iter( follow, dir );
-		
-		if (follow.point() == start_point)
-		  if (new_poly->nextnode(new_poly->firstnode())->point() == next_iter.nextpoint())
-		    return 1;
-
-		new_poly->add( next_iter.point(), &next_iter.poly(), 
-			      next_iter.edgestate() );
-		
-		return make_poly( start_point, follow.point(), next_iter, 
-				done, new_poly );
-	} else	{	// Continue using follow
-	  if (follow.point() == start_point)
-	    if (new_poly->nextnode(new_poly->firstnode())->point() == follow.nextpoint())
-	      return 1;
-
-	  new_poly->add( follow.point(), &follow.poly(), 
-			follow.edgestate() );
-	
-	  return make_poly( start_point, follow.point(), follow, 
-				done, new_poly );
-	}
-}
-
-// a and b are two polygons with their intersection points added.
-// return in polylist all polygons which are 1) inside a and b or 2)
-// inside a and outside b or 3) outside a and inside b
-void
-iter_mesh( const Poly &a, const Poly &b, NodePEdgeList &done, 
-							PolyPList &polylist )
-{
-	ConstPolyIter	iter( a );
-	int				first = 1;
-	
-	while(iter())
-	{
-		const PolyNode	*cur = iter.node();
-
-		DirPolyIter	a_iter( a, cur, b, FORWARD );
-		make_poly( cur->point(), a_iter, polylist, done );
-		if (first)
-		{	
-			// On first point in a polygon you should go backwards
-			first = 0;
-			DirPolyIter	a_bw_iter( a, cur, b, BACKWARD );
-			make_poly( cur->point(), a_bw_iter, polylist, done );
-		}
-		
-		if (cur->link())
-		{
-			DirPolyIter	b_fw_iter( b, cur->link(), a, FORWARD );
-			if (b_fw_iter.edgestate() != Shared)
-				make_poly( cur->point(), b_fw_iter, polylist,  
-									done );
-				
-			DirPolyIter	b_bw_iter( b, cur->link(), a, BACKWARD);
-			if (b_bw_iter.edgestate() != Shared)
-				make_poly( cur->point(), b_bw_iter, polylist, 
-									done );
-		}
-	}
-}
-
-// Determine in which class the polygons in in_list fall. This can be
-// inside a but outside b; than the poygon will be put in a_min_b.
-// Inside b but outside a will put the the polygon in b_min_a.
-// Inside both a and b will put the polygon in a_and_b.
-void	
-assign_polys( const Poly &a, const Poly &b, const PolyPList &in_list, 
-		PolyPList &a_min_b, PolyPList &b_min_a, PolyPList &a_and_b )
-{
-#ifdef DEBUG1
-cout << "a: " << &a << endl;
-cout << a;
-cout << "b: " << &b << endl;
-cout << b;
-#endif
-	PolyPListIter	iter( in_list );
-	
-	while(iter())
-	{
-		Poly	*poly = iter.val();
-		ConstPolyIter	p_i( *poly );
-		// PosAdder has a class with the states True, False and Unkown.
-		// An error (exception) will occur if True of False is set()
-		// if its state is not Unknown.
-		PosAdder	a_parent, b_parent;
-		
-#ifdef DEBUG1
-cout << *poly;
-#endif
-		while(p_i())
-		{
-#ifdef DEBUG1
-cout << (*p_i.node()) << p_i.parent(a) << ',' << p_i.parent(b) << endl;
-#endif
-			// The next two statements collect evidence about
-			// the parenthood. This is done on the basis of
-			// the edge state (shared, none, inside).
-			a_parent.set(p_i.parent(a));
-			b_parent.set(p_i.parent(b));
-		}
-#ifdef notdef
-		if (a_parent() == True && b_parent() == True)
-			a_and_b.add(poly);
-		else if (a_parent() == True)
-			a_min_b.add(poly);
-		else if (a_parent() == UnKnown && b_parent() == UnKnown)
-			// a and b had all sides shared -- 
-			// so probably they are similar
-			a_and_b.add(poly);
-		else {
-			assert( b_parent() == True );
-			b_min_a.add(poly);
-		}
-#else
-		if (a_parent() == TrueFalse || b_parent() == TrueFalse)
-    			// probably not a nor b -- so skip
-    			delete poly;
-		else if (a_parent() != False && b_parent() != False)
-			a_and_b.add(poly);
-		else if (a_parent() == True)
-			a_min_b.add(poly);
-		// else if (a_parent() == UnKnown && b_parent() == UnKnown)
-		//	// a and b had all sides shared -- 
-		//	// so probably they are similar
-		//	a_and_b.add(poly);
-		else {
-		        // If the next assertion failes it could be that
-		        // the polygon is not a and not b.
-			assert( b_parent() == True );	
-			b_min_a.add(poly);
-		}		
-#endif
-	}
-}
-
-void
-poly_min_poly( const Poly &a, const Poly &b, PolyPList &a_min_b )
-{
-	// b is inside a. 
-	// This means we have to split a, as we don't allow polygons with holes.
-	// Split a in three parts: left of b, b and right of b
-	// Split over line top from b, bottom from b.
-	
-	Point			top(b.firstpoint()), bottom(b.firstpoint());
-	const PolyNode	*top_node = b.firstnode(), 
-					*bottom_node = b.firstnode();
-	
-	ConstPolyIter	b_iter(b);
-	
-	while(b_iter())
-		if (b_iter.point() > top)
-		{
-			top = b_iter.point();
-			top_node = b_iter.node();
-		} else if (b_iter.point() < bottom)
-		{
-			bottom = b_iter.point();
-			bottom_node = b_iter.node();
-		}
-
-	assert( top_node != bottom_node );
-				
-	// Find an element of a, so that a line from that point to top does
-	// not intersect with another edge of a, and this point is bigger as
-	// top
-	// Do the same for bottom, at the same time.
-	
-	ConstPolyIter	a_iter(a);
-	const PolyNode	*a_top_node = 0, *a_bottom_node = 0;
-	
-	while(a_iter())
-	{
-		Point	cur(a_iter.point());
-		
-		if (!(	((cur > top) && (a_top_node == 0)) ||
-				((cur < bottom) && (a_bottom_node == 0)) ))
-			continue;
-			
-		Edge	edge(cur, ((cur > top) ? top : bottom));
-		
-		ConstPolyIter	a_iter2(a);
-		
-		int do_intersect = 0;
-		
-		while(a_iter2())
-		{
-			if ((a_iter2.point() == cur) || (a_iter2.nextpoint() == cur))
-				continue;
-			Point	dummy1,dummy2;
-			if (intersect(edge,Edge(a_iter2.point(),a_iter2.nextpoint()),
-														dummy1, dummy2 ))
-			{
-				do_intersect = 1;
-				break;
-			} 
-		}
-		if (do_intersect == 0)
-			if (cur > top)
-				a_top_node = a_iter.node();
-			else
-				a_bottom_node = a_iter.node();
-				
-		if ((a_top_node != 0) && (a_bottom_node != 0))
-			break;
-	}
-	
-	assert((a_top_node != 0) && (a_bottom_node != 0));
-	assert(a_top_node->point() > top);
-	assert(a_bottom_node->point() < bottom);
-	
-	Poly	*left = new Poly(a_top_node->point());
-
-	DirPolyIter	b_back(b,top_node,a,BACKWARD);
-	
-	add_until( left, bottom, b_back );
-	left->add(bottom);
-	
-	DirPolyIter a_forw(a,a_bottom_node,b,FORWARD);
-
-	add_until( left, a_top_node->point(), a_forw);
-	
-	a_min_b.add( left );
-		
-	Poly	*right = new Poly(top);
-
-	add_until( right, a_bottom_node->point(), a_forw );
-	right->add(a_bottom_node->point());
-	add_until( right, top, b_back );
-	
-	a_min_b.add(right);
-}
-
-void	
-add_until( Poly *polyp, const Point &point, DirPolyIter &dpi )
-{
-	do
-	{
-		polyp->add(dpi.point());
-		dpi.next();
-	} while(dpi.point() != point);
-}
-
-// clip the polygons a_org and b_org in the classes a_min_b, b_min_a and
-// a_and_b (see above for the meanings).
-void
-clip_poly( const Poly &a_org, const Poly &b_org, 
-		PolyPList &a_min_b, PolyPList &b_min_a, PolyPList &a_and_b )
-{
-	Poly	a( a_org ), b( b_org );	// a and b can change, so protect
-	
-	a.make_prev();
-	if (a.orientation() != ClockWise)
-	{
-	  a.revert();
-	  a.make_prev();
-	}
-	b.make_prev();
-	if (b.orientation() != ClockWise)
-	{
-	  b.revert();
-	  b.make_prev();
-	}
-
-	int	nr_intersect = intersect( a, b );
-	
-	if (nr_intersect == 0)
-	{
-		// Two case are possible: a and b are disjunct, 
-		// or one is inside the other.
-		if (a.has_point(b.firstpoint()))
-		{
-			// b is inside a
-			a_and_b.add( new Poly(b) );
-			poly_min_poly( a, b, a_min_b );
-		} else if (b.has_point(a.firstpoint()))
-		{
-			// a inside b
-			a_and_b.add( new Poly(a) );
-			poly_min_poly( b, a, b_min_a );
-		} else {
-			// a and b are disjunct
-			a_min_b.add( new Poly(a) );
-			b_min_a.add( new Poly(b) );
-		}
-		
-		return;
-	}
-
-	label_shared( a, b );
-	label_shared( b, a );		
-#ifdef DEBUG_NCLIP
-	// static ofstream	db("debugnc");
-	ostream	&alias = db;
-	alias << setprecision(20);
-	db << "a:\n" << a;
-	db << "b:\n" << b;
-#endif	
-
-	NodePEdgeList	done(100);
-	PolyPList		polylist;
-	
-	iter_mesh( a, b, done, polylist );
-	iter_mesh( b, a, done, polylist );
-	
-	assign_polys( a, b, polylist, a_min_b, b_min_a, a_and_b );
-}
-
+//    nclip: a polygon clip library
+
+//    Copyright (C) 1993  University of Twente
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.2  1994/01/04  12:55:37  klamer
+// Added DEBUG_NCLIP support.
+// Make intersect call itself again if the polygons change.
+// New function label_shared2, called from label_shared.
+// Major changes in label_shared.
+// Make_poly depends on inproducts now rather than on angles.
+// Make sure starting polygons are clockwise oriented.
+//
+// Revision 1.1  1992/12/07  10:46:35  klamer
+// Initial revision
+//
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include	<assert.h>
+
+#include	<graphmat.h>
+#include	<graphadd.h>
+#include        <error.h>
+
+#include	<malloc.h>
+
+#include	<poly.h>
+#include	<primitives.h>
+#include	<posadder.h>
+#include	"nclip.h"
+
+#ifdef DEBUG1
+#include	<iostream.h>
+#include	<poly_io.h>
+#endif
+#ifdef DEBUG_NCLIP
+#include        "poly_io.h"
+#include        <iostream.h>
+#include        <fstream.h>
+#include        <iomanip.h>
+static ofstream db ("debugnc");
+#endif
+
+// Intersect Edge a & b, and return the intersection point in p1 and p2.
+// The return value means the number of intersections. Two intersections
+// mean that a and b are on the same line, the intersection points are in that
+// case the extrema of the joint line segment
+int
+intersect (const Edge & a, const Edge & b, Point & p1, Point & p2)
+{
+  hvec2_t s1, s2;
+
+  int ret =
+    v_inters2 (a.p1 ().hvec (), a.p2 ().hvec (), b.p1 ().hvec (),
+	       b.p2 ().hvec (), &s1, &s2);
+
+  switch (ret)
+    {
+    case 2:
+      p2 = s2;
+      // Fall Through
+    case 1:
+      p1 = s1;
+    }
+
+  return ret;
+}
+
+// calculate all the intersections between a and b. Add the intersection points
+// to a and b.
+// returns total number of intersections found.
+int
+intersect (Poly & a, Poly & b)
+{
+  PolyIter a_iter (a);
+  int res = 0, res2 = 0;
+
+  while (a_iter ())
+    {
+      PolyIter b_iter (b);
+
+      while (b_iter ())
+	{
+	  Point intersect1, intersect2;
+	  int cnt = intersect (a_iter.edge (), b_iter.edge (),
+			       intersect1, intersect2);
+	  res += cnt;
+
+	  if (cnt)
+	    {
+	      res2 += PolyIter::add_point (a_iter, b_iter, intersect1);
+	      if (cnt >= 2)
+		{
+		  res2 += PolyIter::add_point (a_iter, b_iter, intersect2);
+		}
+	    }
+	}
+    }
+
+  if (res2 != 0)
+    return res + intersect (a, b);
+
+  return res;
+}
+
+// Check whether line p1-p2 is inside the polygon pointed by pn. p1 should equal pn.
+// if inside do a_iter.set_inside() else a_iter.set_none(), as it is outside
+void
+label_shared2 (PolyIter & pi, const Point & p1, const Point & p2,
+	       const PolyNode & pn)
+{
+  assert (p1 == pn.point ());
+
+  Point prev = pn.prevnode ().point (), next = pn.nextnode ().point ();
+
+  // The *dir are direction vectors!
+  Point cdir = p2 - p1, pdir = p1 - prev, ndir = next - p1;
+
+  int p_c = (pdir.x () * cdir.y () - pdir.y () * cdir.x ()) >= 0,
+    n_c = (ndir.x () * cdir.y () - ndir.y () * cdir.x ()) >= 0,
+    p_n = (pdir.x () * ndir.y () - pdir.y () * ndir.x ()) >= 0;
+
+  if (p_n)			// pn points to a concave corner?
+    {
+      if (p_c && n_c)
+	pi.set_none ();
+      else
+	pi.set_inside ();
+    }
+  else
+    {
+      if (p_c || n_c)
+	pi.set_none ();
+      else
+	pi.set_inside ();
+    }
+}
+
+// label the edges from polygon a with respect to polygon b. possible
+// labels are: shared, inside and none. inside means that the edge is inside
+// b, none means outside, and shared means that b has the same edge.
+void
+label_shared (Poly & a, const Poly & b)
+{
+  PolyIter a_iter (a);
+
+  while (a_iter ())
+    {
+      const PolyNode *b1, *b2;
+
+      if ((b1 = a_iter.node ()->link ()) &&
+	  (b2 = a_iter.nextnode ()->link ()))
+	{
+	  // Seems shared -- but check
+	  // that b1 and b2 are also connected!
+	  if ((b.nextnode (b1) == b2) || (b.nextnode (b2) == b1))
+	    {
+	      a_iter.set_shared ();
+	      continue;
+	    }			/* else if (b.has_point( a_iter.edge().middle() ))
+				   a_iter.set_inside();
+				   else
+				   a_iter.set_none(); */
+	  //continue;
+	}
+#ifdef notdef
+      if (b1)
+	{
+	  // So a_iter.node() shares a point with b
+	  if (b.has_point (a_iter.nextnode ().point ()))
+	    a_iter.set_inside ();
+	  else
+	    a_iter.set_none ();
+	}
+      else
+	{
+	  // The current node is not on b
+	  if (b.has_point (a_iter.node ().point ()))
+	    a_iter.set_inside ();
+	  else
+	    a_iter.set_none ();
+	}
+
+      //if (b.has_point( a_iter.edge().middle() ))
+      //      a_iter.set_inside();
+      //else
+      //      a_iter.set_none();
+#else
+      if (b1)
+	label_shared2 (a_iter, a_iter.node ()->point (),
+		       a_iter.nextnode ()->point (), *b1);
+      //warning("NYI %s %d\n", __FILE__, __LINE__);
+      else if ((b2 = a_iter.nextnode ()->link ()))
+	label_shared2 (a_iter, a_iter.nextnode ()->point (),
+		       a_iter.node ()->point (), *b2);
+      //warning("NYI %s %d\n", __FILE__, __LINE__);
+      else
+	{
+	  int in1 = b.has_point (a_iter.node ()->point ()),
+	    in2 = b.has_point (a_iter.nextnode ()->point ());
+
+	  if (in1 != in2)
+	    error_at_line (0, 0, __FILE__, __LINE__,
+			   "This should not happen!");
+	  if (in1)
+	    a_iter.set_inside ();
+	  else
+	    a_iter.set_none ();
+	}
+#endif
+    }
+}
+
+// In the two make_poly functions (second one below this one) a new
+// polygon is added to polylist. done contains a list of edge which
+// already are assigned to a polygon, and thus do not belong to this
+// polygon (as the directed edge a->b is only part of one clockwise
+// oriented polygon.) The second make_poly function is a recursive function
+// which finishes the work initiated in the first.
+void
+make_poly (const Point & point,
+	   DirPolyIter & follow, PolyPList & polylist, NodePEdgeList & done)
+{
+  NodePEdge edge (follow);
+
+  if (done.contains (edge))	// Ignore if this edge already is done.
+    return;
+
+  // Make new polygon. start with only one point & edge
+  Poly *new_poly = new Poly (follow.point (), &follow.poly (),
+			     follow.edgestate ());
+
+  // finish the construction of the polygon.
+  if (make_poly (point, point, follow, done, new_poly))
+    {
+      // We want only clockwise oriented polygons!
+      if (new_poly->orientation () != ClockWise)
+	delete new_poly;
+      else
+	polylist.add (new_poly);
+    }
+  else				// Will never happen when only one is returned...
+    delete new_poly;
+}
+
+// second part of make_poly. Continue adding points to new_poly until
+// start_point is reached, and thus the polygon is complete. follow is used
+// to get the next point of the polygon. If the next point is an intersection
+// between the two original polygons, decide whether the other polygon
+// should be followed. This is done by selecting the smallest angle.
+int
+make_poly (const Point & start_point, const Point & point,
+	   DirPolyIter & follow, NodePEdgeList & done, Poly *new_poly)
+{
+  done.add (NodePEdge (follow));
+
+  follow.next ();
+
+  // if (follow.point() == start_point)
+  //      return 1;
+
+  double cur_angle = angle (point, follow.point (), follow.nextpoint ());
+
+  assert (cur_angle != 0);
+
+  IterDirection dir = NONE;
+
+  if (follow.link ())
+    {
+      double other_angle = angle (point, follow.point (),
+				  follow.linknextpoint ());
+      Point d1 = follow.linknextpoint () - follow.point (),
+	d2 = follow.nextpoint () - follow.point (),
+	d3 = follow.point () - point;
+      double inp = d1.x () * d2.y () - d2.x () * d1.y (),
+	inp2 = d1.x () * d3.y () - d3.x () * d1.y ();
+      int lf = inp > 0,
+	ld = inp2 > 0,
+	df = (d3.x () * d2.y () - d2.x () * d3.y ()) > 0,
+	condition = (lf + ld + df) >= 2;
+      // if (inp2 = 0)        // Similar to other_angle = 0
+      if (point == follow.linknextpoint ())
+	condition = 0;
+      assert ((cur_angle != other_angle) ||
+	      (inp != 0) || (follow.linknextpoint () == follow.nextpoint ()));
+      assert ((other_angle != 0) ||
+	      (inp2 != 0) || (follow.linknextpoint () == point));
+      //assert((cur_angle == other_angle) ||
+      //       ((((cur_angle - other_angle) > 0))
+      //      ^ condition));
+#ifdef notdef
+      if ((other_angle != 0) && (other_angle == cur_angle ?
+				 inp > 0 : other_angle < cur_angle))
+	{
+	  assert (condition);
+#else
+      if (condition)
+	{
+#endif
+	  cur_angle = other_angle;
+	  dir = FORWARD;
+	  d2 = d1;
+	}			//else
+      //assert(!condition);
+
+      other_angle = angle (point, follow.point (), follow.linkprevpoint ());
+      d1 = follow.linkprevpoint () - follow.point ();
+      //      d2 = follow.nextpoint() - follow.point();
+      inp = d1.x () * d2.y () - d2.x () * d1.y ();
+      inp2 = d1.x () * d3.y () - d3.x () * d1.y ();
+      lf = inp > 0;
+      ld = inp2 > 0;
+      df = (d3.x () * d2.y () - d2.x () * d3.y ()) > 0;
+      condition = (lf + ld + df) >= 2;
+      // if (inp2 = 0)
+      if (point == follow.linkprevpoint ())
+	condition = 0;
+      assert ((cur_angle != other_angle) ||
+	      (inp != 0) || (follow.linkprevpoint () == follow.nextpoint ()));
+      assert ((other_angle != 0) ||
+	      (inp2 != 0) || (follow.linkprevpoint () == point));
+      //assert((cur_angle == other_angle) ||
+      //       ((((cur_angle - other_angle) > 0))
+      //      ^ condition));
+#ifdef notdef
+      if ((other_angle != 0) && (other_angle == cur_angle ?
+				 inp > 0 : other_angle < cur_angle))
+	{
+	  assert (condition);
+#else
+      if (condition)
+	{
+#endif
+	  // No need to update cur_angle
+	  dir = BACKWARD;
+	}			//else
+      // assert(!condition);
+    }
+
+  if (dir != NONE)
+    {
+
+      DirPolyIter next_iter (follow, dir);
+
+      if (follow.point () == start_point)
+	if (new_poly->nextnode (new_poly->firstnode ())->point () ==
+	    next_iter.nextpoint ())
+	  return 1;
+
+      new_poly->add (next_iter.point (), &next_iter.poly (),
+		     next_iter.edgestate ());
+
+      return make_poly (start_point, follow.point (), next_iter,
+			done, new_poly);
+    }
+  else
+    {				// Continue using follow
+      if (follow.point () == start_point)
+	if (new_poly->nextnode (new_poly->firstnode ())->point () ==
+	    follow.nextpoint ())
+	  return 1;
+
+      new_poly->add (follow.point (), &follow.poly (), follow.edgestate ());
+
+      return make_poly (start_point, follow.point (), follow, done, new_poly);
+    }
+}
+
+// a and b are two polygons with their intersection points added.
+// return in polylist all polygons which are 1) inside a and b or 2)
+// inside a and outside b or 3) outside a and inside b
+void
+iter_mesh (const Poly & a, const Poly & b, NodePEdgeList & done,
+	   PolyPList & polylist)
+{
+  ConstPolyIter iter (a);
+  int first = 1;
+
+  while (iter ())
+    {
+      const PolyNode *cur = iter.node ();
+
+      DirPolyIter a_iter (a, cur, b, FORWARD);
+      make_poly (cur->point (), a_iter, polylist, done);
+      if (first)
+	{
+	  // On first point in a polygon you should go backwards
+	  first = 0;
+	  DirPolyIter a_bw_iter (a, cur, b, BACKWARD);
+	  make_poly (cur->point (), a_bw_iter, polylist, done);
+	}
+
+      if (cur->link ())
+	{
+	  DirPolyIter b_fw_iter (b, cur->link (), a, FORWARD);
+	  if (b_fw_iter.edgestate () != Shared)
+	    make_poly (cur->point (), b_fw_iter, polylist, done);
+
+	  DirPolyIter b_bw_iter (b, cur->link (), a, BACKWARD);
+	  if (b_bw_iter.edgestate () != Shared)
+	    make_poly (cur->point (), b_bw_iter, polylist, done);
+	}
+    }
+}
+
+// Determine in which class the polygons in in_list fall. This can be
+// inside a but outside b; than the poygon will be put in a_min_b.
+// Inside b but outside a will put the the polygon in b_min_a.
+// Inside both a and b will put the polygon in a_and_b.
+void
+assign_polys (const Poly & a, const Poly & b, const PolyPList & in_list,
+	      PolyPList & a_min_b, PolyPList & b_min_a, PolyPList & a_and_b)
+{
+#ifdef DEBUG1
+  cout << "a: " << &a << endl;
+  cout << a;
+  cout << "b: " << &b << endl;
+  cout << b;
+#endif
+  PolyPListIter iter (in_list);
+
+  while (iter ())
+    {
+      Poly *poly = iter.val ();
+      ConstPolyIter p_i (*poly);
+      // PosAdder has a class with the states True, False and Unkown.
+      // An error (exception) will occur if True of False is set()
+      // if its state is not Unknown.
+      PosAdder a_parent, b_parent;
+
+#ifdef DEBUG1
+      cout << *poly;
+#endif
+      while (p_i ())
+	{
+#ifdef DEBUG1
+	  cout << (*p_i.node ()) << p_i.parent (a) << ',' << p_i.
+	    parent (b) << endl;
+#endif
+	  // The next two statements collect evidence about
+	  // the parenthood. This is done on the basis of
+	  // the edge state (shared, none, inside).
+	  a_parent.set (p_i.parent (a));
+	  b_parent.set (p_i.parent (b));
+	}
+#ifdef notdef
+      if (a_parent () == True && b_parent () == True)
+	a_and_b.add (poly);
+      else if (a_parent () == True)
+	a_min_b.add (poly);
+      else if (a_parent () == UnKnown && b_parent () == UnKnown)
+	// a and b had all sides shared --
+	// so probably they are similar
+	a_and_b.add (poly);
+      else
+	{
+	  assert (b_parent () == True);
+	  b_min_a.add (poly);
+	}
+#else
+      if (a_parent () == TrueFalse || b_parent () == TrueFalse)
+	// probably not a nor b -- so skip
+	delete poly;
+      else if (a_parent () != False && b_parent () != False)
+	a_and_b.add (poly);
+      else if (a_parent () == True)
+	a_min_b.add (poly);
+      // else if (a_parent() == UnKnown && b_parent() == UnKnown)
+      //      // a and b had all sides shared --
+      //      // so probably they are similar
+      //      a_and_b.add(poly);
+      else
+	{
+	  // If the next assertion failes it could be that
+	  // the polygon is not a and not b.
+	  assert (b_parent () == True);
+	  b_min_a.add (poly);
+	}
+#endif
+    }
+}
+
+void
+poly_min_poly (const Poly & a, const Poly & b, PolyPList & a_min_b)
+{
+  // b is inside a.
+  // This means we have to split a, as we don't allow polygons with holes.
+  // Split a in three parts: left of b, b and right of b
+  // Split over line top from b, bottom from b.
+
+  Point top (b.firstpoint ()), bottom (b.firstpoint ());
+  const PolyNode *top_node = b.firstnode (), *bottom_node = b.firstnode ();
+
+  ConstPolyIter b_iter (b);
+
+  while (b_iter ())
+    if (b_iter.point () > top)
+      {
+	top = b_iter.point ();
+	top_node = b_iter.node ();
+      }
+    else if (b_iter.point () < bottom)
+      {
+	bottom = b_iter.point ();
+	bottom_node = b_iter.node ();
+      }
+
+  assert (top_node != bottom_node);
+
+  // Find an element of a, so that a line from that point to top does
+  // not intersect with another edge of a, and this point is bigger as
+  // top
+  // Do the same for bottom, at the same time.
+
+  ConstPolyIter a_iter (a);
+  const PolyNode *a_top_node = 0, *a_bottom_node = 0;
+
+  while (a_iter ())
+    {
+      Point cur (a_iter.point ());
+
+      if (!(((cur > top) && (a_top_node == 0)) ||
+	    ((cur < bottom) && (a_bottom_node == 0))))
+	continue;
+
+      Edge edge (cur, ((cur > top) ? top : bottom));
+
+      ConstPolyIter a_iter2 (a);
+
+      int do_intersect = 0;
+
+      while (a_iter2 ())
+	{
+	  if ((a_iter2.point () == cur) || (a_iter2.nextpoint () == cur))
+	    continue;
+	  Point dummy1, dummy2;
+	  if (intersect (edge, Edge (a_iter2.point (), a_iter2.nextpoint ()),
+			 dummy1, dummy2))
+	    {
+	      do_intersect = 1;
+	      break;
+	    }
+	}
+      if (do_intersect == 0)
+	{
+	  if (cur > top)
+	    a_top_node = a_iter.node ();
+	  else
+	    a_bottom_node = a_iter.node ();
+	}
+
+      if ((a_top_node != 0) && (a_bottom_node != 0))
+	break;
+    }
+
+  assert ((a_top_node != 0) && (a_bottom_node != 0));
+  assert (a_top_node->point () > top);
+  assert (a_bottom_node->point () < bottom);
+
+  Poly *left = new Poly (a_top_node->point ());
+
+  DirPolyIter b_back (b, top_node, a, BACKWARD);
+
+  add_until (left, bottom, b_back);
+  left->add (bottom);
+
+  DirPolyIter a_forw (a, a_bottom_node, b, FORWARD);
+
+  add_until (left, a_top_node->point (), a_forw);
+
+  a_min_b.add (left);
+
+  Poly *right = new Poly (top);
+
+  add_until (right, a_bottom_node->point (), a_forw);
+  right->add (a_bottom_node->point ());
+  add_until (right, top, b_back);
+
+  a_min_b.add (right);
+}
+
+void
+add_until (Poly *polyp, const Point & point, DirPolyIter & dpi)
+{
+  do
+    {
+      polyp->add (dpi.point ());
+      dpi.next ();
+    }
+  while (dpi.point () != point);
+}
+
+// clip the polygons a_org and b_org in the classes a_min_b, b_min_a and
+// a_and_b (see above for the meanings).
+void
+clip_poly (const Poly & a_org, const Poly & b_org,
+	   PolyPList & a_min_b, PolyPList & b_min_a, PolyPList & a_and_b)
+{
+  Poly a (a_org), b (b_org);	// a and b can change, so protect
+
+  a.make_prev ();
+  if (a.orientation () != ClockWise)
+    {
+      a.revert ();
+      a.make_prev ();
+    }
+  b.make_prev ();
+  if (b.orientation () != ClockWise)
+    {
+      b.revert ();
+      b.make_prev ();
+    }
+
+  int nr_intersect = intersect (a, b);
+
+  if (nr_intersect == 0)
+    {
+      // Two case are possible: a and b are disjunct,
+      // or one is inside the other.
+      if (a.has_point (b.firstpoint ()))
+	{
+	  // b is inside a
+	  a_and_b.add (new Poly (b));
+	  poly_min_poly (a, b, a_min_b);
+	}
+      else if (b.has_point (a.firstpoint ()))
+	{
+	  // a inside b
+	  a_and_b.add (new Poly (a));
+	  poly_min_poly (b, a, b_min_a);
+	}
+      else
+	{
+	  // a and b are disjunct
+	  a_min_b.add (new Poly (a));
+	  b_min_a.add (new Poly (b));
+	}
+
+      return;
+    }
+
+  label_shared (a, b);
+  label_shared (b, a);
+#ifdef DEBUG_NCLIP
+  // static ofstream      db("debugnc");
+  ostream & alias = db;
+  alias << setprecision (20);
+  db << "a:\n" << a;
+  db << "b:\n" << b;
+#endif
+
+  NodePEdgeList done (100);
+  PolyPList polylist;
+
+  iter_mesh (a, b, done, polylist);
+  iter_mesh (b, a, done, polylist);
+
+  assign_polys (a, b, polylist, a_min_b, b_min_a, a_and_b);
+}
--- clippoly-0.11.orig/nclip.h
+++ clippoly-0.11/nclip.h
@@ -1,66 +1,66 @@
-//    nclip: a polygon clip library
-
-//    Copyright (C) 1993  Klamer Schutte
-
-//    klamer@mi.el.utwente.nl
-
-//    This library is free software; you can redistribute it and/or
-//    modify it under the terms of the GNU Library General Public
-//    License as published by the Free Software Foundation; either
-//    version 2 of the License, or (at your option) any later version.
-
-//    This library is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//    Library General Public License for more details.
-
-//    You should have received a copy of the GNU Library General Public
-//    License along with this library; if not, write to the Free
-//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-#ifndef	NCLIP_H
-#define	NCLIP_H	"$Header: /cvsroot/clippoly/clippoly/nclip.h,v 1.5 2005/02/28 17:21:12 klamer Exp $"
-
-// $Log: nclip.h,v $
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.1  1993/10/27  14:43:51  klamer
-// Initial revision
-//
-// Revision 1.1  1993/10/27  14:43:51  klamer
-// Initial revision
-//
-// Revision 1.1  1992/12/07  10:46:35  klamer
-// Initial revision
-//
-
-#ifdef _GNUG__
-#pragma interface
-#endif
-
-class	Poly;
-// class	PolyPList;
-class	Edge;
-class	DirPolyIter;
-// class	PolyNodePList;
-class	Point;
-// class	NodePEdgeList;
-
-void	clip_poly( const Poly &a, const Poly &b, 
-			PolyPList &a_min_b, PolyPList &b_min_a, PolyPList &a_and_b );
-int		intersect( const Edge &a, const Edge &b, Point &p1, Point &p2 );
-int		intersect( Poly &a, Poly &b );
-void	label_shared( Poly & a, const Poly & b );
-void	make_poly( const Point &point, DirPolyIter &follow, 
-			PolyPList &polylist, NodePEdgeList &done );
-int 	make_poly( const Point &start_point, const Point &point, 
-			DirPolyIter &follow, NodePEdgeList &done, 
-			Poly * new_poly );
-void	assign_polys( const Poly &a, const Poly &b, const PolyPList &in_list, 
-			PolyPList &a_min_b, PolyPList &b_min_a, PolyPList &a_and_b );
-void	poly_min_poly( const Poly &a, const Poly &b, PolyPList &a_min_b );
-void	add_until( Poly *, const Point &, DirPolyIter & );
-
-#endif	/* NCLIP_H */
+//    nclip: a polygon clip library
+
+//    Copyright (C) 1993  Klamer Schutte
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifndef	NCLIP_H
+#define	NCLIP_H
+
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.1  1993/10/27  14:43:51  klamer
+// Initial revision
+//
+// Revision 1.1  1993/10/27  14:43:51  klamer
+// Initial revision
+//
+// Revision 1.1  1992/12/07  10:46:35  klamer
+// Initial revision
+//
+
+#ifdef _GNUG__
+#pragma interface
+#endif
+
+class Poly;
+// class        PolyPList;
+class Edge;
+class DirPolyIter;
+// class        PolyNodePList;
+class Point;
+// class        NodePEdgeList;
+
+void clip_poly (const Poly & a, const Poly & b,
+		PolyPList & a_min_b, PolyPList & b_min_a,
+		PolyPList & a_and_b);
+int intersect (const Edge & a, const Edge & b, Point & p1, Point & p2);
+int intersect (Poly & a, Poly & b);
+void label_shared (Poly & a, const Poly & b);
+void make_poly (const Point & point, DirPolyIter & follow,
+		PolyPList & polylist, NodePEdgeList & done);
+int make_poly (const Point & start_point, const Point & point,
+	       DirPolyIter & follow, NodePEdgeList & done, Poly * new_poly);
+void assign_polys (const Poly & a, const Poly & b, const PolyPList & in_list,
+		   PolyPList & a_min_b, PolyPList & b_min_a,
+		   PolyPList & a_and_b);
+void poly_min_poly (const Poly & a, const Poly & b, PolyPList & a_min_b);
+void add_until (Poly *, const Point &, DirPolyIter &);
+
+#endif /* NCLIP_H */
--- clippoly-0.11.orig/out_file.dist
+++ clippoly-0.11/out_file.dist
@@ -1,34 +1,34 @@
-a_min_b:
-1	-1
-0.5	0
-1.5	0
-PolyMagic
-0.25	0.5
-0	1
-0.5	1
-PolyMagic
-1.5	1
-2	1
-1.75	0.5
-PolyMagic
-b_min_a:
-0.5	0
-0	0
-0.25	0.5
-PolyMagic
-0.5	1
-1	2
-1.5	1
-PolyMagic
-1.75	0.5
-2	0
-1.5	0
-PolyMagic
-a_and_b:
-0.5	0
-0.25	0.5
-0.5	1
-1.5	1
-1.75	0.5
-1.5	0
-PolyMagic
+a_min_b:
+1	-1
+0.5	0
+1.5	0
+PolyMagic
+0.25	0.5
+0	1
+0.5	1
+PolyMagic
+1.5	1
+2	1
+1.75	0.5
+PolyMagic
+b_min_a:
+0.5	0
+0	0
+0.25	0.5
+PolyMagic
+0.5	1
+1	2
+1.5	1
+PolyMagic
+1.75	0.5
+2	0
+1.5	0
+PolyMagic
+a_and_b:
+0.5	0
+0.25	0.5
+0.5	1
+1.5	1
+1.75	0.5
+1.5	0
+PolyMagic
--- clippoly-0.11.orig/poly.cc
+++ clippoly-0.11/poly.cc
@@ -1,585 +1,595 @@
-static const char rcs_id[] = "$Header: /cvsroot/clippoly/clippoly/poly.cc,v 1.7 2005/03/11 14:18:21 klamer Exp $";
-
-//    nclip: a polygon clip library
-
-//    Copyright (C) 1993  University of Twente
-
-//    klamer@mi.el.utwente.nl
-
-//    This library is free software; you can redistribute it and/or
-//    modify it under the terms of the GNU Library General Public
-//    License as published by the Free Software Foundation; either
-//    version 2 of the License, or (at your option) any later version.
-
-//    This library is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//    Library General Public License for more details.
-
-//    You should have received a copy of the GNU Library General Public
-//    License along with this library; if not, write to the Free
-//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-// $Log: poly.cc,v $
-// Revision 1.7  2005/03/11 14:18:21  klamer
-// Fixed namespace clash for abs(double) happening in RedHat 7.2 linux i386.
-//
-// Revision 1.6  2005/02/28 21:12:05  klamer
-// Made changes such that gcc 3.4.2 compiles silent with -ansi -pedantic -Wall.
-//
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.2  1994/01/04  12:55:37  klamer
-// Made copy constructor of PolyNode a dummy, and added one which also
-// sets parent.
-// Make orientation use area rather than angles.
-// Added Poly::revert() member.
-// PolyIter::add: start with check whether current point already is in
-// polygon.
-// PolyIter::add_point(): now returns number of nodes added.
-// ConstPolyIter::parent(const Poly &): Changed conditions.
-//
-// Revision 1.1  1993/10/27  14:44:07  klamer
-// Initial revision
-//
-// Revision 1.1  1992/12/07  10:46:35  klamer
-// Initial revision
-//
-
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
-#include	<assert.h>
-
-#include	<err.h>
-
-#include	"poly.h"
-#include	"posadder.h"
-//#include	"boundingbox.h"
-//#include	"poly_use.h"
-
-static const char h_rcs_id[] = POLY_H;
-
-#ifndef M_PI
-#define M_PI            3.14159265358979323846  /* pi */
-#endif
-
-PolyNode::PolyNode( const PolyNode &)
-{
-  // Argh! use constructor which sets parent!
-  error("This should not happen %s %d\n", __FILE__, __LINE__ );
-}
-
-PolyNode::PolyNode( const PolyNode &copy , const Poly *parent )
-    : p(copy.p), prev(0), _link(0), _parent_poly( parent), _edgestate( Unknown )
-{
-	if (copy.next)
-	  next = new PolyNode( *copy.next, parent );
-	else
-		next = 0;
-}
-
-PolyNode::~PolyNode()
-{
-	if (next)
-		delete next;
-}
-
-const Poly *
-PolyNode::parent_poly() const
-{
-	assert(_parent_poly != 0);
-	
-	return _parent_poly;
-}
-
-NodePEdge::NodePEdge( const DirPolyIter &dpi )
-{
-	const PolyNode	*node = dpi.node(),
-					*link = node->link();
-	
-	if (link)
-		if (link < node)
-			n1 = link;
-		else
-			n1 = node;
-	else
-		n1 = node;
-
-	node = dpi.nextnode();
-	link = node->link();
-	
-	if (link)
-		if (link < node)
-			n2 = link;
-		else
-			n2 = node;
-	else
-		n2 = node;
-}
-
-void
-Poly::make_prev() const
-{
-	PolyIter	iter(*(Poly *)this);
-	PolyNode	*last = 0;
-	
-	while(iter())
-	{
-		iter.node()->prev = last;
-		last = iter.node();
-	}
-	
-	((Poly *)this)->prev = last;
-}
-
-const PolyNode *
-Poly::nextnode(const PolyNode *node) const
-{
-	if (node->next)
-		return node->next;
-
-	return list;
-}
-
-const PolyNode *
-Poly::prevnode(const PolyNode *node) const
-{
-	assert(prev);
-	
-	if (node->prev)
-		return node->prev;
-
-	return prev;
-}
-
-void
-Poly::add( const Point &p, const Poly *parent, EdgeState edgestate )
-{
-	if (!prev)
-		make_prev();
-		
-	PolyNode	*new_node = new PolyNode( p, parent, edgestate );
-	
-	new_node->prev = prev;
-	new_node->next = 0;
-	
-	assert( prev->next == 0 );
-	prev->next = new_node;
-	prev = new_node;
-}
-	
-Orientation
-Poly::orientation() const
-{
-	if (!prev)
-		make_prev();
-		
-	ConstPolyIter	iter(*this);
-	
-	double	tot_angle = 0;
-	double	area = 0;
-	Point	first;
-	int	first_flag = 1;
-	
-	while(iter())
-	{
-		tot_angle += angle( iter.prevpoint(), iter.point(), 
-						iter.nextpoint() ) - M_PI;
-		if (first_flag)
-		{
-			first_flag = 0;
-			first = iter.point();
-			continue;
-		}
-		// Point	&p1 = iter.point(), &p2 = iter.nextpoint();
-		// NOTE: last step in iter also is not needed!
-		Point	p1 = iter.point() - first, 
-			p2 = iter.nextpoint() - first;
-		area += p1.x() * p2.y() - p2.x() * p1.y();
-	}
-	area /= 2.0;
-	
-	assert(area != 0);
-	assert((area * tot_angle > 0) ||
-	       (fabs(fabs(tot_angle) - M_PI * 2.0) > 0.0001));
-
-#ifndef notdef
-	if (area < 0)
-		return ClockWise;
-	else
-		return CounterClockWise;
-#else
-	if (tot_angle < 0)
-	{
-		assert(tot_angle < -M_PI * 1.9999);
-		assert(tot_angle > -M_PI * 2.0001);
-
-		return ClockWise;
-	} else {
-		assert(tot_angle > M_PI * 1.9999);
-		assert(tot_angle < M_PI * 2.0001);
-
-		return CounterClockWise;
-	}
-#endif
-}
-
-
-double
-Poly::area() const
-{
-	if (!prev)
-		make_prev();
-		
-	ConstPolyIter	iter(*this);
-	
-	double	ret = 0;
-	
-	Point	first;
-	int	first_flag = 1;
-	
-	while(iter())
-	{
-		if (first_flag)
-		{
-			first_flag = 0;
-			first = iter.point();
-			continue;
-		}
-		Point	p1 = iter.point() - first, 
-			p2 = iter.nextpoint() - first;
-		ret += p1.x() * p2.y() - p2.x() * p1.y();
-	}
-
-	return ret / 2.0;
-}
-
-void
-Poly::revert()
-{
-  if (!prev)
-    make_prev();
-  
-  PolyNode	*next;
-  
-  for(PolyNode *cur = list; cur != 0; cur = next)
-  {
-    next = cur->next;
-    cur->next = cur->prev;
-    cur->prev = next;
-  }
-  
-  PolyNode	*tmp = prev;
-  prev = list;
-  list = tmp;
-  
-  // warning("NYI %s %d\n", __FILE__, __LINE__);
-}
-
-int
-intersect_right( const Edge &edge, const Point &point )
-{
-	if ((edge.p1().y() >= point.y()) && (edge.p2().y() >= point.y()))
-		return 0;
-	if ((edge.p1().y() < point.y()) && (edge.p2().y() < point.y()))
-		return 0;
-		
-	if (edge.p1().y() == edge.p2().y())
-		return 0;		// Tricky! This could give errors!
-		
-	double x = (point.y() - edge.p1().y()) * 
-		(edge.p2().x() - edge.p1().x()) / (edge.p2().y() - edge.p1().y())
-		+ edge.p1().x();
-		
-	if (x > point.x())	// Tricky! Is >= better?
-		return 1;
-	return 0;
-}
-
-// is point inside *this?
-int	
-Poly::has_point( const Point &point ) const
-{
-	PolyIter	iter( *(Poly *)((void *)this) );
-	int		cnt = 0;
-	
-	while(iter())
-		cnt += intersect_right( iter.edge(), point );
-		
-	return cnt % 2; 
-}
-
-double
-Poly::xmin() const
-{
-	ConstPolyIter	iter(*this);
-	
-	iter();
-	double	res = iter.point().x();
-
-	while(iter())
-	{
-		double	c = iter.point().x();
-		if (c < res)
-			res = c;
-	}
-	
-	return res;
-}
-
-double
-Poly::xmax() const
-{
-	ConstPolyIter	iter(*this);
-	
-	iter();
-	double	res = iter.point().x();
-
-	while(iter())
-	{
-		double	c = iter.point().x();
-		if (c > res)
-			res = c;
-	}
-	
-	return res;
-}
-
-double
-Poly::ymin() const
-{
-	ConstPolyIter	iter(*this);
-	
-	iter();
-	double	res = iter.point().y();
-
-	while(iter())
-	{
-		double	c = iter.point().y();
-		if (c < res)
-			res = c;
-	}
-	
-	return res;
-}
-
-double
-Poly::ymax() const
-{
-	ConstPolyIter	iter(*this);
-	
-	iter();
-	double	res = iter.point().y();
-
-	while(iter())
-	{
-		double	c = iter.point().y();
-		if (c > res)
-			res = c;
-	}
-	
-	return res;
-}
-
-PolyIter::PolyIter( Poly &_poly )
-	: poly(_poly), app_next(poly.list)
-{ 
-}
-
-int
-PolyIter::operator() ()
-{
-	cur = app_next;
-	
-	if (cur != 0)
-	{
-		app_next = cur->next;
-		return 1;
-	} else
-		return 0;
-}
-
-PolyNode *	
-PolyIter::add( const Point &point, int &new_point )
-{
-  PolyIter	chk(poly);
-  
-  while(chk())
-    if (point == chk.node()->point())
-      return chk.node();
-  
-	if (point == cur->p)
-	  warning("This should not happen! %s, %d\n", __FILE__, __LINE__ );
-		// return cur;
-		
-	double	d = len( cur->p - point );
-	assert( d <= len( cur->p - AppNext()->p ) );
-	PolyNode	*last = cur, *p = next( cur );
-	
-	for(  ;d > len( cur->p - p->p ); last = p, p = next( p ))
-	  ;	// Go to next node, as next node is on same side as current node
-
-	if (p->p == point)
-	  warning("This should not happen! %s, %d\n", __FILE__, __LINE__ );
-		// return p;
-			
-	p = new PolyNode( point, &poly, last->next );
-	new_point++;
-	last->next = p;
-	if (p->next)
-		p->next->prev = p;
-	else if (poly.prev)
-	{
-		assert(poly.prev == last);
-		poly.prev = p;
-	}
-	p->prev = last;
-	
-	return p;
-}
-
-int	
-PolyIter::add_point( PolyIter &a, PolyIter &b, const Point &p )
-{
-  int	res = 0;
-  
-	PolyNode	*node_a = a.add( p, res );
-	PolyNode	*node_b = b.add( p, res );
-
-	assert((node_a->_link == 0) || (node_a->_link == node_b));	
-	node_a->_link = node_b;
-	assert((node_b->_link == 0) || (node_b->_link == node_a));	
-	node_b->_link = node_a;
-	
-	return res;
-}
-
-ConstPolyIter::ConstPolyIter( const Poly &_poly )
-	: polyiter( *(Poly *)(void *)&_poly )
-{ 
-}
-
-LogicStates
-ConstPolyIter::parent(const Poly &poly)
-{
-	switch(node()->edgestate())
-	{case None:
-		if (&poly == node()->parent_poly())
-			return True;
-		else
-		  {
-		    if (node()->link() != 0)
-		      return UnKnown; // Prob. True
-		    else
-		      return False;
-		  }
-	case Shared:
-		return UnKnown;
-	case Inside:
-		if (&poly == node()->parent_poly())
-			return UnKnown;
-		else {
-		  if (node()->link() != 0)
-		    return UnKnown;
-		  else
-		    return True;
-		}
-	case Unknown:
-	default:
-		fatal("This should not happen %s %d\n", __FILE__, __LINE__);
-	}
-	
-	return UnKnown;
-}
-
-DirPolyIter::DirPolyIter( const Poly &poly, const PolyNode *node,
-								const Poly &link, IterDirection dir )
-	: _poly(poly), _linkpoly(link), _dir(dir), _node(node)
-{ 
-	if (! _poly.prev)
-		_poly.make_prev();
-	if (!_linkpoly.prev)
-		_linkpoly.make_prev();
-}
-
-DirPolyIter::DirPolyIter( const DirPolyIter &dpi, IterDirection dir )
-	: _poly(dpi.linkpoly()), _linkpoly( dpi._poly ), _dir(dir), 
-	  _node( dpi.node()->link() )
-{ 
-	if (! _poly.prev)
-		_poly.make_prev();
-	if (!_linkpoly.prev)
-		_linkpoly.make_prev();
-}
-
-const PolyNode *
-DirPolyIter::nextnode() const
-{
-	switch(dir())
-	{case FORWARD:
-		return _poly.nextnode(node());
-	case BACKWARD:
-		return  _poly.prevnode(node());
-	default:
-		assert(0);
-	}
-	return 0;	// Should not be reached
-}
-
-const PolyNode *
-DirPolyIter::prevnode() const
-{
-	switch(dir())
-	{case FORWARD:
-		return _poly.prevnode(node());
-	case BACKWARD:
-		return  _poly.nextnode(node());
-	default:
-		assert(0);
-	}
-	return 0;	// Should not be reached
-}
-
-EdgeState
-DirPolyIter::edgestate() const
-{
-	if (dir() == FORWARD)
-		return node()->edgestate();
-		
-	return nextnode()->edgestate();
-}
-
-#ifdef notdef
-int
-Poly::intersect_table( int hor, Vec &intersection_table, double h )
-{
-	ConstPolyIter	iter(*this);
-	iter();
-	BoundingBox	bbox(iter.point());
-	while(iter())
-		bbox.add(iter.point());
-
-	Point	left( hor ? bbox.xmin()-1 : 0, hor ? 0 : bbox.ymin()-1 ), 
-			right( hor ? bbox.xmax()+1 : 0, hor ? 0 : bbox.ymax()+1 );
-	
-	if (hor)
-		left.y() = right.y() = h;
-	else
-		left.x() = right.x() = h;
-
-	int		nr_inters;
-	
-	if (hor)
-		create_intersection_table(*this, left, right, 
-						nr_inters, intersection_table, x, y );
-	else
-		create_intersection_table(*this, left, right, 
-						nr_inters, intersection_table, y, x );
-	
-	return nr_inters;
-}
-#endif
+//    nclip: a polygon clip library
+
+//    Copyright (C) 1993  University of Twente
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+// Revision 1.7  2005/03/11 14:18:21  klamer
+// Fixed namespace clash for abs(double) happening in RedHat 7.2 linux i386.
+//
+// Revision 1.6  2005/02/28 21:12:05  klamer
+// Made changes such that gcc 3.4.2 compiles silent with -ansi -pedantic -Wall.
+//
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.2  1994/01/04  12:55:37  klamer
+// Made copy constructor of PolyNode a dummy, and added one which also
+// sets parent.
+// Make orientation use area rather than angles.
+// Added Poly::revert() member.
+// PolyIter::add: start with check whether current point already is in
+// polygon.
+// PolyIter::add_point(): now returns number of nodes added.
+// ConstPolyIter::parent(const Poly &): Changed conditions.
+//
+// Revision 1.1  1993/10/27  14:44:07  klamer
+// Initial revision
+//
+// Revision 1.1  1992/12/07  10:46:35  klamer
+// Initial revision
+//
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include	<assert.h>
+
+#include	<error.h>
+
+#include	"poly.h"
+#include	"posadder.h"
+//#include      "boundingbox.h"
+//#include      "poly_use.h"
+
+#ifndef M_PI
+#define M_PI            3.14159265358979323846	/* pi */
+#endif
+
+PolyNode::PolyNode (const PolyNode &)
+{
+  // Argh! use constructor which sets parent!
+  error_at_line (0, 0, __FILE__, __LINE__, "This should not happen");
+}
+
+PolyNode::PolyNode (const PolyNode & copy, const Poly *parent):
+p (copy.p),
+prev (0),
+_link (0),
+_parent_poly (parent),
+_edgestate (Unknown)
+{
+  if (copy.next)
+    next = new PolyNode (*copy.next, parent);
+  else
+    next = 0;
+}
+
+PolyNode::~PolyNode ()
+{
+  if (next)
+    delete next;
+}
+
+const Poly *
+PolyNode::parent_poly () const
+{
+  assert (_parent_poly != 0);
+
+  return _parent_poly;
+}
+
+NodePEdge::NodePEdge (const DirPolyIter & dpi)
+{
+  const PolyNode *node = dpi.node (), *link = node->link ();
+
+  if (link)
+    if (link < node)
+      n1 = link;
+    else
+      n1 = node;
+  else
+    n1 = node;
+
+  node = dpi.nextnode ();
+  link = node->link ();
+
+  if (link)
+    if (link < node)
+      n2 = link;
+    else
+      n2 = node;
+  else
+    n2 = node;
+}
+
+void
+Poly::make_prev () const
+{
+  PolyIter iter (*(Poly *) this);
+  PolyNode *last = 0;
+
+  while (iter ())
+    {
+      iter.node ()->prev = last;
+      last = iter.node ();
+    }
+
+  ((Poly *) this)->prev = last;
+}
+
+const PolyNode *
+Poly::nextnode (const PolyNode *node) const
+{
+  if (node->next)
+    return node->next;
+
+  return list;
+}
+
+const PolyNode *
+Poly::prevnode (const PolyNode *node) const
+{
+  assert (prev);
+
+  if (node->prev)
+    return node->prev;
+
+  return prev;
+}
+
+void
+Poly::add (const Point & p, const Poly *parent, EdgeState edgestate)
+{
+  if (!prev)
+    make_prev ();
+
+  PolyNode *new_node = new PolyNode (p, parent, edgestate);
+
+  new_node->prev = prev;
+  new_node->next = 0;
+
+  assert (prev->next == 0);
+  prev->next = new_node;
+  prev = new_node;
+}
+
+Orientation Poly::orientation ()const
+{
+  if (!prev)
+    make_prev ();
+
+  ConstPolyIter
+  iter (*this);
+
+  double
+    tot_angle = 0;
+  double
+    area = 0;
+  Point
+    first;
+  int
+    first_flag = 1;
+
+  while (iter ())
+    {
+      tot_angle += angle (iter.prevpoint (), iter.point (),
+			  iter.nextpoint ()) - M_PI;
+      if (first_flag)
+	{
+	  first_flag = 0;
+	  first = iter.point ();
+	  continue;
+	}
+      // Point        &p1 = iter.point(), &p2 = iter.nextpoint();
+      // NOTE: last step in iter also is not needed!
+      Point
+	p1 = iter.point () - first, p2 = iter.nextpoint () - first;
+      area += p1.x () * p2.y () - p2.x () * p1.y ();
+    }
+  area /= 2.0;
+
+  assert (area != 0);
+  assert ((area * tot_angle > 0) ||
+	  (fabs (fabs (tot_angle) - M_PI * 2.0) > 0.0001));
+
+#ifndef notdef
+  if (area < 0)
+    return ClockWise;
+  else
+    return CounterClockWise;
+#else
+  if (tot_angle < 0)
+    {
+      assert (tot_angle < -M_PI * 1.9999);
+      assert (tot_angle > -M_PI * 2.0001);
+
+      return ClockWise;
+    }
+  else
+    {
+      assert (tot_angle > M_PI * 1.9999);
+      assert (tot_angle < M_PI * 2.0001);
+
+      return CounterClockWise;
+    }
+#endif
+}
+
+
+double
+Poly::area () const
+{
+  if (!prev)
+    make_prev ();
+
+  ConstPolyIter iter (*this);
+
+  double ret = 0;
+
+  Point first;
+  int first_flag = 1;
+
+  while (iter ())
+    {
+      if (first_flag)
+	{
+	  first_flag = 0;
+	  first = iter.point ();
+	  continue;
+	}
+      Point p1 = iter.point () - first, p2 = iter.nextpoint () - first;
+      ret += p1.x () * p2.y () - p2.x () * p1.y ();
+    }
+
+  return ret / 2.0;
+}
+
+void
+Poly::revert ()
+{
+  if (!prev)
+    make_prev ();
+
+  PolyNode *next;
+
+  for (PolyNode * cur = list; cur != 0; cur = next)
+    {
+      next = cur->next;
+      cur->next = cur->prev;
+      cur->prev = next;
+    }
+
+  PolyNode *tmp = prev;
+  prev = list;
+  list = tmp;
+
+  // warning("NYI %s %d\n", __FILE__, __LINE__);
+}
+
+int
+intersect_right (const Edge & edge, const Point & point)
+{
+  if ((edge.p1 ().y () >= point.y ()) && (edge.p2 ().y () >= point.y ()))
+    return 0;
+  if ((edge.p1 ().y () < point.y ()) && (edge.p2 ().y () < point.y ()))
+    return 0;
+
+  if (edge.p1 ().y () == edge.p2 ().y ())
+    return 0;			// Tricky! This could give errors!
+
+  double x = (point.y () - edge.p1 ().y ()) *
+    (edge.p2 ().x () - edge.p1 ().x ()) / (edge.p2 ().y () - edge.p1 ().y ())
+    + edge.p1 ().x ();
+
+  if (x > point.x ())		// Tricky! Is >= better?
+    return 1;
+  return 0;
+}
+
+// is point inside *this?
+int
+Poly::has_point (const Point & point) const
+{
+  PolyIter iter (*(Poly *) ((void *) this));
+  int cnt = 0;
+
+  while (iter ())
+    cnt += intersect_right (iter.edge (), point);
+
+  return cnt % 2;
+}
+
+double
+Poly::xmin () const
+{
+  ConstPolyIter iter (*this);
+
+  iter ();
+  double res = iter.point ().x ();
+
+  while (iter ())
+    {
+      double c = iter.point ().x ();
+      if (c < res)
+	res = c;
+    }
+
+  return res;
+}
+
+double
+Poly::xmax () const
+{
+  ConstPolyIter iter (*this);
+
+  iter ();
+  double res = iter.point ().x ();
+
+  while (iter ())
+    {
+      double c = iter.point ().x ();
+      if (c > res)
+	res = c;
+    }
+
+  return res;
+}
+
+double
+Poly::ymin () const
+{
+  ConstPolyIter iter (*this);
+
+  iter ();
+  double res = iter.point ().y ();
+
+  while (iter ())
+    {
+      double c = iter.point ().y ();
+      if (c < res)
+	res = c;
+    }
+
+  return res;
+}
+
+double
+Poly::ymax () const
+{
+  ConstPolyIter iter (*this);
+
+  iter ();
+  double res = iter.point ().y ();
+
+  while (iter ())
+    {
+      double c = iter.point ().y ();
+      if (c > res)
+	res = c;
+    }
+
+  return res;
+}
+
+PolyIter::PolyIter (Poly & _poly):poly (_poly), app_next (poly.list)
+{
+}
+
+int
+PolyIter::operator () ()
+{
+  cur = app_next;
+
+  if (cur != 0)
+    {
+      app_next = cur->next;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+PolyNode *
+PolyIter::add (const Point & point, int &new_point)
+{
+  PolyIter chk (poly);
+
+  while (chk ())
+    if (point == chk.node ()->point ())
+      return chk.node ();
+
+  if (point == cur->p)
+    error_at_line (0, 0, __FILE__, __LINE__, "This should not happen");
+  // return cur;
+
+  double d = len (cur->p - point);
+  assert (d <= len (cur->p - AppNext ()->p));
+  PolyNode *last = cur, *p = next (cur);
+
+  for (; d > len (cur->p - p->p); last = p, p = next (p))
+    ;				// Go to next node, as next node is on same side as current node
+
+  if (p->p == point)
+    error_at_line (0, 0, __FILE__, __LINE__, "This should not happen");
+  // return p;
+
+  p = new PolyNode (point, &poly, last->next);
+  new_point++;
+  last->next = p;
+  if (p->next)
+    p->next->prev = p;
+  else if (poly.prev)
+    {
+      assert (poly.prev == last);
+      poly.prev = p;
+    }
+  p->prev = last;
+
+  return p;
+}
+
+int
+PolyIter::add_point (PolyIter & a, PolyIter & b, const Point & p)
+{
+  int res = 0;
+
+  PolyNode *node_a = a.add (p, res);
+  PolyNode *node_b = b.add (p, res);
+
+  assert ((node_a->_link == 0) || (node_a->_link == node_b));
+  node_a->_link = node_b;
+  assert ((node_b->_link == 0) || (node_b->_link == node_a));
+  node_b->_link = node_a;
+
+  return res;
+}
+
+ConstPolyIter::ConstPolyIter (const Poly & _poly):
+polyiter (*(Poly *)(void *) &_poly)
+{
+}
+
+LogicStates ConstPolyIter::parent (const Poly & poly)
+{
+  switch (node ()->edgestate ())
+    {
+    case None:
+      if (&poly == node ()->parent_poly ())
+	return True;
+      else
+	{
+	  if (node ()->link () != 0)
+	    return UnKnown;	// Prob. True
+	  else
+	    return False;
+	}
+    case Shared:
+      return UnKnown;
+    case Inside:
+      if (&poly == node ()->parent_poly ())
+	return UnKnown;
+      else
+	{
+	  if (node ()->link () != 0)
+	    return UnKnown;
+	  else
+	    return True;
+	}
+    case Unknown:
+    default:
+      error_at_line (1, 0, __FILE__, __LINE__, "This should not happen");
+    }
+
+  return UnKnown;
+}
+
+DirPolyIter::DirPolyIter (const Poly & poly, const PolyNode *node,
+			  const Poly & link, IterDirection dir):
+_poly (poly),
+_linkpoly (link),
+_dir (dir),
+_node (node)
+{
+  if (!_poly.prev)
+    _poly.make_prev ();
+  if (!_linkpoly.prev)
+    _linkpoly.make_prev ();
+}
+
+DirPolyIter::DirPolyIter (const DirPolyIter & dpi, IterDirection dir):
+_poly (dpi.linkpoly ()),
+_linkpoly (dpi._poly),
+_dir (dir),
+_node (dpi.node ()->link ())
+{
+  if (!_poly.prev)
+    _poly.make_prev ();
+  if (!_linkpoly.prev)
+    _linkpoly.make_prev ();
+}
+
+const PolyNode *
+DirPolyIter::nextnode () const
+{
+  switch (dir ())
+    {
+    case FORWARD:
+      return _poly.nextnode (node ());
+    case BACKWARD:
+      return _poly.prevnode (node ());
+    default:
+      assert (0);
+    }
+  return 0;			// Should not be reached
+}
+
+const PolyNode *
+DirPolyIter::prevnode () const
+{
+  switch (dir ())
+    {
+    case FORWARD:
+      return _poly.prevnode (node ());
+    case BACKWARD:
+      return _poly.nextnode (node ());
+    default:
+      assert (0);
+    }
+  return 0;			// Should not be reached
+}
+
+EdgeState DirPolyIter::edgestate ()const
+{
+  if (dir () == FORWARD)
+    return node ()->edgestate ();
+
+  return nextnode ()->edgestate ();
+}
+
+#ifdef notdef
+int
+Poly::intersect_table (int hor, Vec & intersection_table, double h)
+{
+  ConstPolyIter iter (*this);
+  iter ();
+  BoundingBox bbox (iter.point ());
+  while (iter ())
+    bbox.add (iter.point ());
+
+  Point left (hor ? bbox.xmin () - 1 : 0, hor ? 0 : bbox.ymin () - 1),
+    right (hor ? bbox.xmax () + 1 : 0, hor ? 0 : bbox.ymax () + 1);
+
+  if (hor)
+    left.y () = right.y () = h;
+  else
+    left.x () = right.x () = h;
+
+  int nr_inters;
+
+  if (hor)
+    create_intersection_table (*this, left, right,
+			       nr_inters, intersection_table, x, y);
+  else
+    create_intersection_table (*this, left, right,
+			       nr_inters, intersection_table, y, x);
+
+  return nr_inters;
+}
+#endif
--- clippoly-0.11.orig/poly.h
+++ clippoly-0.11/poly.h
@@ -1,318 +1,412 @@
-//    nclip: a polygon clip library
-
-//    Copyright (C) 1993  Klamer Schutte
-
-//    klamer@mi.el.utwente.nl
-
-//    This library is free software; you can redistribute it and/or
-//    modify it under the terms of the GNU Library General Public
-//    License as published by the Free Software Foundation; either
-//    version 2 of the License, or (at your option) any later version.
-
-//    This library is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//    Library General Public License for more details.
-
-//    You should have received a copy of the GNU Library General Public
-//    License along with this library; if not, write to the Free
-//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-#ifndef	POLY_H
-#define	POLY_H	"$Header: /cvsroot/clippoly/clippoly/poly.h,v 1.6 2005/02/28 21:12:05 klamer Exp $"
-
-// $Log: poly.h,v $
-// Revision 1.6  2005/02/28 21:12:05  klamer
-// Made changes such that gcc 3.4.2 compiles silent with -ansi -pedantic -Wall.
-//
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.2  1994/01/04  12:55:37  klamer
-// Changed PolyNode constructors.
-// Added Poly::revert() member.
-//
-// Revision 1.1  1993/10/27  14:43:52  klamer
-// Initial revision
-//
-// Revision 1.2  1992/12/07  13:32:35  klamer
-// Deleted comments from Poly::Poly(const Point &) in-class defined
-// constructor.
-//
-// Revision 1.1  1992/12/07  10:46:35  klamer
-// Initial revision
-//
-
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-#include <iostream>
-
-#ifndef PRIMITIVES_H
-#include	<primitives.h>
-#endif
-#ifndef SET_H
-#include	<set.h>
-#endif
-#ifndef POSADDER_H
-#include	<posadder.h>
-#endif
-
-int		intersect_right( const Edge &edge, const Point &point );
-
-enum EdgeState { Unknown, None, Shared, Inside };
-// enum LogicStates;
-class Vec;
-
-class PolyNode
-{
-	friend class Poly;
-	friend class PolyIter;
-	friend class ConstPolyIter;
-	friend std::ostream &operator<<(std::ostream &, const PolyNode &);
-
-public:
-	PolyNode	*link()
-				{ return _link; }
-	const PolyNode	*link() const
-				{ return _link; }
-	const Point	&point() const
-				{ return p; }
-	EdgeState	edgestate() const
-				{ return _edgestate; }
-	const PolyNode	&prevnode() const;
-				// { return *_parent_poly->prevnode(this); }
-	const PolyNode	&nextnode() const;
-				// { return *_parent_poly->nextnode(this); }
-
-private:	
-	PolyNode( const PolyNode &copy );	// Don't use
-	PolyNode( const PolyNode &copy, const Poly *parent );
-	PolyNode( const Point &point, const Poly *parent, PolyNode *tail = 0)
-    		: p( point ), next( tail ), prev(0), _link( 0 ), 
-                  _parent_poly( parent ), _edgestate( ::Unknown )
-		{ }
-	PolyNode( const Point &point, const Poly *parent, EdgeState es )
-		: p( point ), next( 0 ), prev(0), _link( 0 ), 
-		  _parent_poly( parent ), _edgestate( es ) 
-		{ }
-	~PolyNode();
-	
-	void		operator=( PolyNode node );	// Don't use it!
-	
-	Point		p;
-	PolyNode	*next, *prev;
-	PolyNode	*_link;
-	const Poly	*_parent_poly;
-	const Poly	*parent_poly() const;
-	
-	EdgeState _edgestate;
-
-};
-
-class DirPolyIter;
-
-class NodePEdge
-{
-	const PolyNode	*n1, *n2;
-	friend class Set<NodePEdge>;
-	friend class RSet<NodePEdge>;
-	NodePEdge()
-		{ }
-	
-public:
-	NodePEdge( const PolyNode *n_1, const PolyNode *n_2 )
-		: n1( n_1 ), n2( n_2 )
-		{ }
-	NodePEdge( const DirPolyIter &dpi );
-	int		operator==( const NodePEdge &cmp ) const
-			{ return (n1 == cmp.n1) && (n2 == cmp.n2); }
-};
-
-typedef Set<const PolyNode *> 		PolyNodePList;
-typedef SetIter<const PolyNode *>	PolyNodePListIter;
-typedef	RSet<NodePEdge>				NodePEdgeList;
-typedef	RSetIter<NodePEdge>			NodePEdgeListIter;
-
-enum Orientation { ClockWise, CounterClockWise };
-
-class Poly
-{
-private:
-	friend class PolyIter;
-	friend class DirPolyIter;
-	
-	PolyNode		*list, *prev;
-	Poly &operator=( const Poly &copy );		// Don't use it!
-	
-public:
-	Poly( const Poly &copy )
-		: list( new PolyNode( *copy.list, this ) ), prev( 0 )
-		{ }
-//	Poly( const PolyNode *copy, const Poly *parent )
-//		: list( new PolyNode( copy, parent ) ), prev(0)
-//		{ }
-	Poly( const Point &p, const Poly *parent, EdgeState es )
-		: list( new PolyNode( p, parent, es ) ), prev(0)
-		{ }
-	Poly( const Point &p )
-		// : list( new PolyNode( &PolyNode(p), 0 ) ), prev(0)
-		: list( new PolyNode( p, this ) ), prev(0)
-		{ }
-	~Poly()
-		{ delete list; }
-
-	void	add( const Point &p, const Poly *parent, EdgeState es );
-	void	add( const Point &p )
-		{	add( p, 0, ::Unknown ); }	// 0 or this ???
-			
-	int	has_point( const Point &point ) const;	// point inside *this?
-
-	const PolyNode	*nextnode( const PolyNode *node ) const;
-	
-	Orientation		orientation() const;
-	double			area() const;
-	void			revert();
-
-	void			make_prev() const;
-	const PolyNode	*prevnode( const PolyNode *node ) const;
-	
-	const Point		&firstpoint() const
-					{ return list->point(); }
-	const PolyNode	*firstnode() const
-					{ return list; }
-					
-	double			xmin() const;
-	double			xmax() const;
-	double			ymin() const;
-	double			ymax() const;
-
-	int			intersect_table( int hor, Vec &it, double h );
-};
-
-inline const PolyNode &
-PolyNode::prevnode() const
-{ 
-  return *_parent_poly->prevnode(this); 
-}
-
-inline const PolyNode &
-PolyNode::nextnode() const				
-{ 
-  return *_parent_poly->nextnode(this); 
-}
-
-typedef Set<Poly *> PolyPList;
-typedef SetIter<Poly *>	PolyPListIter;
-
-class PolyIter
-{
-	Poly		&poly;
-	PolyNode	*cur, *app_next;
-	PolyNode	*AppNext()
-				{ return (app_next != 0) ? app_next : poly.list; }
-	const PolyNode	*AppNext() const
-				{ return (app_next != 0) ? app_next : poly.list; }
-	PolyNode	*next(PolyNode *node)
-				{ return (node->next != 0) ? node->next : poly.list; }
-	PolyNode	*add( const Point &point, int &new_point );
-	PolyNode	*add( const Point &point )
-	  			{ int dummy; return add(point, dummy); }
-	
-public:
-	PolyIter( Poly &poly );
-	void		reset()
-				{ app_next = poly.list; }
-
-	int			operator() ();
-	PolyNode	*node()
-				{ return cur; }
-	const PolyNode	*node() const
-				{ return cur; }
-	const PolyNode	*nextnode() const
-				{ return AppNext(); }
-	const PolyNode	*prevnode() const
-				{ return poly.prevnode(node()); }
-		
-	Edge		edge() const
-				{ return Edge( cur->p, AppNext()->p ); }
-	static int	add_point( PolyIter &a, PolyIter &b, const Point &p );
-	
-	void		set_shared()
-				{ cur->_edgestate = ::Shared; }
-	void		set_inside()
-				{ cur->_edgestate = ::Inside; }
-	void		set_none()
-				{ cur->_edgestate = ::None; }
-};
-
-enum IterDirection { FORWARD, BACKWARD, NONE };
-
-class DirPolyIter
-{
-	const Poly		&_poly, &_linkpoly;
-	const IterDirection	_dir;
-	const PolyNode	*_node;
-	
-	IterDirection	dir() const
-					{ return _dir; }
-	const Poly		&linkpoly() const
-					{ return _linkpoly; }
-	const PolyNode	*prevnode() const;
-					
-public:
-	DirPolyIter( const Poly &poly, const PolyNode *node,
-							const Poly &link, IterDirection dir );
-
-	// Continue on link  
-	DirPolyIter( const DirPolyIter &dpi, IterDirection dir );
-	
-	void			next()
-					{ _node = nextnode(); }
-	const PolyNode	*node() const
-					{ return _node; }
-	const PolyNode	*nextnode() const;
-	const PolyNode	*link() const
-					{ return node()->link(); }
-	const Point		&point() const
-					{ return node()->point(); }
-	const Point		&nextpoint() const
-					{ return nextnode()->point(); }
-	const Point		&linknextpoint() const
-					{ return linkpoly().nextnode(link())->point(); }
-	const Point		&linkprevpoint() const
-					{ return linkpoly().prevnode(link())->point(); }
-	const Poly		&poly() const
-					{ return _poly; }
-	EdgeState		edgestate() const;
-};	
-
-class ConstPolyIter 
-{
-	PolyIter		polyiter;
-	const PolyNode	*prevnode() const
-					{ return polyiter.prevnode(); }
-	const PolyNode	*nextnode() const
-					{ return polyiter.nextnode(); }
-					
-public:
-	ConstPolyIter( const Poly &poly );
-
-	int				operator() ()
-					{ return polyiter(); }
-	const PolyNode	*node() const
-					{ return polyiter.node(); }
-	LogicStates		parent(const Poly &poly);
-	const Point		&point() const
-					{ return node()->point(); }
-	const Point		&prevpoint() const
-					{ return prevnode()->point(); }
-	const Point		&nextpoint() const
-					{ return nextnode()->point(); }
-	Edge			edge() const
-					{ return polyiter.edge(); }
-};
-	
-#endif	/* POLY_H */
+//    nclip: a polygon clip library
+
+//    Copyright (C) 1993  Klamer Schutte
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+#ifndef	POLY_H
+#define	POLY_H
+
+// Revision 1.7  2005/03/12 16:32:36  klamer
+// Changes to keep Visual C++ (vc98) silent while compiling.
+//
+// Revision 1.6  2005/02/28 21:12:05  klamer
+// Made changes such that gcc 3.4.2 compiles silent with -ansi -pedantic -Wall.
+//
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.2  1994/01/04  12:55:37  klamer
+// Changed PolyNode constructors.
+// Added Poly::revert() member.
+//
+// Revision 1.1  1993/10/27  14:43:52  klamer
+// Initial revision
+//
+// Revision 1.2  1992/12/07  13:32:35  klamer
+// Deleted comments from Poly::Poly(const Point &) in-class defined
+// constructor.
+//
+// Revision 1.1  1992/12/07  10:46:35  klamer
+// Initial revision
+//
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <iostream>
+
+#ifndef PRIMITIVES_H
+#include	<primitives.h>
+#endif
+#ifndef SET_H
+#include	<set.h>
+#endif
+#ifndef POSADDER_H
+#include	<posadder.h>
+#endif
+
+int intersect_right (const Edge & edge, const Point & point);
+
+enum EdgeState
+{ Unknown, None, Shared, Inside };
+// enum LogicStates;
+class Vec;
+
+class Poly;
+
+class PolyNode
+{
+  friend class Poly;
+  friend class PolyIter;
+  friend class ConstPolyIter;
+  friend std::ostream & operator<< (std::ostream &, const PolyNode &);
+
+public:
+    PolyNode * link ()
+  {
+    return _link;
+  }
+  const PolyNode *link () const
+  {
+    return _link;
+  }
+  const Point & point () const
+  {
+    return p;
+  }
+  EdgeState edgestate () const
+  {
+    return _edgestate;
+  }
+  const PolyNode & prevnode () const;
+  // { return *_parent_poly->prevnode(this); }
+  const PolyNode & nextnode () const;
+  // { return *_parent_poly->nextnode(this); }
+
+private:
+  PolyNode (const PolyNode & copy);	// Don't use
+  PolyNode (const PolyNode & copy, const Poly * parent);
+PolyNode (const Point & point, const Poly * parent, PolyNode * tail = 0):p (point), next (tail), prev (0), _link (0),
+    _parent_poly (parent),
+    _edgestate (::Unknown)
+  {
+  }
+  PolyNode (const Point & point, const Poly * parent, EdgeState es):p (point),
+    next (0), prev (0), _link (0), _parent_poly (parent), _edgestate (es)
+  {
+  }
+  ~PolyNode ();
+
+  void operator= (PolyNode node);	// Don't use it!
+
+  Point p;
+  PolyNode *next, *prev;
+  PolyNode *_link;
+  const Poly *_parent_poly;
+  const Poly *parent_poly () const;
+
+  EdgeState _edgestate;
+
+};
+
+class DirPolyIter;
+
+class NodePEdge
+{
+  const PolyNode *n1, *n2;
+  friend class Set < NodePEdge >;
+  friend class RSet < NodePEdge >;
+    NodePEdge ()
+  {
+  }
+
+public:
+    NodePEdge (const PolyNode * n_1, const PolyNode * n_2):n1 (n_1), n2 (n_2)
+  {
+  }
+  NodePEdge (const DirPolyIter & dpi);
+  int operator== (const NodePEdge & cmp) const
+  {
+    return (n1 == cmp.n1) && (n2 == cmp.n2);
+  }
+};
+
+typedef Set < const PolyNode *>PolyNodePList;
+typedef SetIter < const PolyNode *>PolyNodePListIter;
+typedef RSet < NodePEdge > NodePEdgeList;
+typedef RSetIter < NodePEdge > NodePEdgeListIter;
+
+enum Orientation
+{ ClockWise, CounterClockWise };
+
+class Poly
+{
+private:
+  friend class PolyIter;
+  friend class DirPolyIter;
+
+  PolyNode *list, *prev;
+    Poly & operator= (const Poly & copy);	// Don't use it!
+
+public:
+    Poly (const Poly & copy):prev (0)
+  {
+    list = new PolyNode (*copy.list, this);
+  }
+//      Poly( const PolyNode *copy, const Poly *parent )
+//              : list( new PolyNode( copy, parent ) ), prev(0)
+//              { }
+  Poly (const Point & p, const Poly * parent,
+	EdgeState es):list (new PolyNode (p, parent, es)), prev (0)
+  {
+  }
+  Poly (const Point & p)
+    // : list( new PolyNode( &PolyNode(p), 0 ) ), prev(0)
+  : prev (0)
+  {
+    list = new PolyNode (p, this);
+  }
+  ~Poly ()
+  {
+    delete list;
+  }
+
+  void add (const Point & p, const Poly * parent, EdgeState es);
+  void add (const Point & p)
+  {
+    add (p, 0,::Unknown);
+  }				// 0 or this ???
+
+  int has_point (const Point & point) const;	// point inside *this?
+
+  const PolyNode *nextnode (const PolyNode * node) const;
+
+  Orientation orientation () const;
+  double area () const;
+  void revert ();
+
+  void make_prev () const;
+  const PolyNode *prevnode (const PolyNode * node) const;
+
+  const Point & firstpoint () const
+  {
+    return list->point ();
+  }
+  const PolyNode *firstnode () const
+  {
+    return list;
+  }
+
+  double xmin () const;
+  double xmax () const;
+  double ymin () const;
+  double ymax () const;
+
+  int intersect_table (int hor, Vec & it, double h);
+};
+
+inline const PolyNode &
+PolyNode::prevnode () const
+{
+  return *_parent_poly->prevnode (this);
+}
+
+inline const PolyNode &
+PolyNode::nextnode () const
+{
+  return *_parent_poly->nextnode (this);
+}
+
+typedef Set < Poly * >PolyPList;
+typedef SetIter < Poly * >PolyPListIter;
+
+class PolyIter
+{
+  Poly & poly;
+  PolyNode *cur, *app_next;
+  PolyNode *AppNext ()
+  {
+    return (app_next != 0) ? app_next : poly.list;
+  }
+  const PolyNode *AppNext () const
+  {
+    return (app_next != 0) ? app_next : poly.list;
+  }
+  PolyNode *next (PolyNode * node)
+  {
+    return (node->next != 0) ? node->next : poly.list;
+  }
+  PolyNode *add (const Point & point, int &new_point);
+  PolyNode *add (const Point & point)
+  {
+    int dummy;
+    return add (point, dummy);
+  }
+
+public:
+  PolyIter (Poly & poly);
+  void reset ()
+  {
+    app_next = poly.list;
+  }
+
+  int operator () ();
+  PolyNode *node ()
+  {
+    return cur;
+  }
+  const PolyNode *node () const
+  {
+    return cur;
+  }
+  const PolyNode *nextnode () const
+  {
+    return AppNext ();
+  }
+  const PolyNode *prevnode () const
+  {
+    return poly.prevnode (node ());
+  }
+
+  Edge edge () const
+  {
+    return Edge (cur->p, AppNext ()->p);
+  }
+  static int add_point (PolyIter & a, PolyIter & b, const Point & p);
+
+  void set_shared ()
+  {
+    cur->_edgestate =::Shared;
+  }
+  void set_inside ()
+  {
+    cur->_edgestate =::Inside;
+  }
+  void set_none ()
+  {
+    cur->_edgestate =::None;
+  }
+};
+
+enum IterDirection
+{ FORWARD, BACKWARD, NONE };
+
+class DirPolyIter
+{
+  const Poly & _poly, &_linkpoly;
+  const IterDirection _dir;
+  const PolyNode *_node;
+
+  IterDirection dir () const
+  {
+    return _dir;
+  }
+  const Poly & linkpoly () const
+  {
+    return _linkpoly;
+  }
+  const PolyNode *prevnode () const;
+
+public:
+    DirPolyIter (const Poly & poly, const PolyNode * node,
+		 const Poly & link, IterDirection dir);
+
+  // Continue on link
+    DirPolyIter (const DirPolyIter & dpi, IterDirection dir);
+
+  void next ()
+  {
+    _node = nextnode ();
+  }
+  const PolyNode *node () const
+  {
+    return _node;
+  }
+  const PolyNode *nextnode () const;
+  const PolyNode *link () const
+  {
+    return node ()->link ();
+  }
+  const Point & point () const
+  {
+    return node ()->point ();
+  }
+  const Point & nextpoint () const
+  {
+    return nextnode ()->point ();
+  }
+  const Point & linknextpoint () const
+  {
+    return linkpoly ().nextnode (link ())->point ();
+  }
+  const Point & linkprevpoint () const
+  {
+    return linkpoly ().prevnode (link ())->point ();
+  }
+  const Poly & poly () const
+  {
+    return _poly;
+  }
+  EdgeState edgestate () const;
+};
+
+class ConstPolyIter
+{
+  PolyIter polyiter;
+  const PolyNode *prevnode () const
+  {
+    return polyiter.prevnode ();
+  }
+  const PolyNode *nextnode () const
+  {
+    return polyiter.nextnode ();
+  }
+
+public:
+    ConstPolyIter (const Poly & poly);
+
+  int operator () ()
+  {
+    return polyiter ();
+  }
+  const PolyNode *node () const
+  {
+    return polyiter.node ();
+  }
+  LogicStates parent (const Poly & poly);
+  const Point & point () const
+  {
+    return node ()->point ();
+  }
+  const Point & prevpoint () const
+  {
+    return prevnode ()->point ();
+  }
+  const Point & nextpoint () const
+  {
+    return nextnode ()->point ();
+  }
+  Edge edge () const
+  {
+    return polyiter.edge ();
+  }
+};
+
+#endif /* POLY_H */
--- clippoly-0.11.orig/poly_io.cc
+++ clippoly-0.11/poly_io.cc
@@ -1,191 +1,182 @@
-static const char rcs_id[] = "$Header: /cvsroot/clippoly/clippoly/poly_io.cc,v 1.5 2005/02/28 17:21:12 klamer Exp $";
-
-//    nclip: a polygon clip library
-
-//    Copyright (C) 1993  University of Twente
-
-//    klamer@mi.el.utwente.nl
-
-//    This library is free software; you can redistribute it and/or
-//    modify it under the terms of the GNU Library General Public
-//    License as published by the Free Software Foundation; either
-//    version 2 of the License, or (at your option) any later version.
-
-//    This library is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//    Library General Public License for more details.
-
-//    You should have received a copy of the GNU Library General Public
-//    License along with this library; if not, write to the Free
-//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-// $Log: poly_io.cc,v $
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.1  1992/12/07  10:46:35  klamer
-// Initial revision
-//
-
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
-#include	<string>
-#include	<iostream>
-
-#include	<err.h>
-
-#include	<poly.h>
-#include	<primitives.h>
-#include	<posadder.h>
-
-#include	<graphmat.h>
-//#include	"poly3node.h"
-//#include	"poly3.h"
-//#include	"poly2.h"
-
-#include	"poly_io.h"
-
-static const char h_rcs_id[] = POLY_IO_H;
-
-using namespace std;
-
-Poly 	*
-read_poly( istream &in )
-{
-	Point	p;
-	
-	in >> p;
-	
-	Poly	*new_poly = new Poly( p );
-	
-	while( in >> p )
-		new_poly->add( p );
-
-	string	magic;
-	
-	in.clear();
-	in >> magic;
-	
-	if (magic != POLY_MAGIC)
-		fatal("read_poly: wrong magic (%s)\n", magic.c_str());
-		
-	return new_poly;
-}
-		
-istream &
-operator>>(istream &in, Point &p)
-{
-	double	x, y;
-	
-	in >> x >> y;
-
-	if (!in)	// Failure?
-		return in;
-	
-	p = Point(x,y);
-
-	return in;
-}
-
-std::ostream	&
-operator<<(std::ostream &out, const PolyPList &pl)
-{
-	PolyPListIter	iter(pl);
-	
-	while(iter())
-		out << *iter.val();
-		
-	return out;
-}
-
-std::ostream &
-operator<<(std::ostream &out, const Poly &poly)
-{
-	ConstPolyIter	iter(poly);
-	
-	while(iter())
-		out << (iter.point());
-
-	out << POLY_MAGIC << endl;
-			
-	return out;
-}
-
-std::ostream &
-operator<<(std::ostream &out, const PolyNode &poly)
-{
-	out << poly.p << "next: " << poly.next << " prev: " << poly.prev 
-		<< " link: " << poly._link << " state: " 
-		<< poly.edgestate() 
-		<< " parent: " << (void *) poly._parent_poly << endl;
-	
-	return out;
-}
-
-std::ostream &
-operator<<(std::ostream &out, const Point &p)
-{
-	out << p.x() << '\t' << p.y() << endl;
-	
-	return out;
-}
-
-std::ostream &
-operator<<(std::ostream &out, enum LogicStates state)
-{
-	switch(state)
-	{case UnKnown:
-		out << "UnKnown";
-		break;
-	case True:
-		out << "True";
-		break;
-	case False:
-		out << "False";
-		break;
-	case TrueFalse:
-		out << "TrueFalse";
-		break;
-	default:
-		error("<<: Unknown value in LogicStates: %d\n", (int)state);
-		out << (int)state;
-	}
-	
-	return out;
-}
-
-std::ostream &
-operator<<(std::ostream &out, enum EdgeState state)
-{
-	switch(state)
-	{case Unknown:
-		out << "Unknown";
-		break;
-	case None:
-		out << "None";
-		break;
-	case Shared:
-		out << "Shared";
-		break;
-	case Inside:
-		out << "Inside";
-		break;
-	default:
-		error("<<: Unknown value in LogicStates: %d\n", (int)state);
-		out << (int)state;
-	}
-	
-	return out;
-}
-
-std::ostream &
-operator<<(std::ostream&out, const hvec3_t &v)
-{
-	out << v_x(v) << ", " << v_y(v) << ", " << v_z(v) << ", " << v_w(v);
-
-	return out;
-} 
+//    nclip: a polygon clip library
+
+//    Copyright (C) 1993  University of Twente
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.1  1992/12/07  10:46:35  klamer
+// Initial revision
+//
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include	<string>
+#include	<iostream>
+
+#include	<error.h>
+
+#include	<poly.h>
+#include	<primitives.h>
+#include	<posadder.h>
+
+#include	<graphmat.h>
+//#include      "poly3node.h"
+//#include      "poly3.h"
+//#include      "poly2.h"
+
+#include	"poly_io.h"
+
+using namespace std;
+
+Poly *
+read_poly (istream & in)
+{
+  Point p;
+
+  in >> p;
+
+  Poly *new_poly = new Poly (p);
+
+  while (in >> p)
+    new_poly->add (p);
+
+  string magic;
+
+  in.clear ();
+  in >> magic;
+
+  if (magic != POLY_MAGIC)
+    error_at_line (1, 0, __FILE__, __LINE__,
+		   "read_poly: wrong magic (%s)", magic.c_str ());
+
+  return new_poly;
+}
+
+istream & operator>> (istream & in, Point & p)
+{
+  double x, y;
+
+  in >> x >> y;
+
+  if (!in)			// Failure?
+    return in;
+
+  p = Point (x, y);
+
+  return in;
+}
+
+std::ostream & operator<< (std::ostream & out, const PolyPList & pl)
+{
+  PolyPListIter iter (pl);
+
+  while (iter ())
+    out << *iter.val ();
+
+  return out;
+}
+
+std::ostream & operator<< (std::ostream & out, const Poly & poly)
+{
+  ConstPolyIter iter (poly);
+
+  while (iter ())
+    out << (iter.point ());
+
+  out << POLY_MAGIC << endl;
+
+  return out;
+}
+
+std::ostream & operator<< (std::ostream & out, const PolyNode & poly)
+{
+  out << poly.p << "next: " << poly.next << " prev: " << poly.prev
+    << " link: " << poly._link << " state: "
+    << poly.edgestate () << " parent: " << (void *) poly._parent_poly << endl;
+
+  return out;
+}
+
+std::ostream & operator<< (std::ostream & out, const Point & p)
+{
+  out << p.x () << '\t' << p.y () << endl;
+
+  return out;
+}
+
+std::ostream & operator<< (std::ostream & out, enum LogicStates state)
+{
+  switch (state)
+    {
+    case UnKnown:
+      out << "UnKnown";
+      break;
+    case True:
+      out << "True";
+      break;
+    case False:
+      out << "False";
+      break;
+    case TrueFalse:
+      out << "TrueFalse";
+      break;
+    default:
+      error_at_line (0, 0, __FILE__, __LINE__,
+		     "Unknown value in LogicStates: %d", (int) state);
+      out << (int) state;
+    }
+
+  return out;
+}
+
+std::ostream & operator<< (std::ostream & out, enum EdgeState state)
+{
+  switch (state)
+    {
+    case Unknown:
+      out << "Unknown";
+      break;
+    case None:
+      out << "None";
+      break;
+    case Shared:
+      out << "Shared";
+      break;
+    case Inside:
+      out << "Inside";
+      break;
+    default:
+      error_at_line (0, 0, __FILE__, __LINE__,
+		     "Unknown value in LogicStates: %d", (int) state);
+      out << (int) state;
+    }
+
+  return out;
+}
+
+std::ostream & operator<< (std::ostream & out, const hvec3_t & v)
+{
+  out << v_x (v) << ", " << v_y (v) << ", " << v_z (v) << ", " << v_w (v);
+
+  return out;
+}
--- clippoly-0.11.orig/poly_io.h
+++ clippoly-0.11/poly_io.h
@@ -1,59 +1,58 @@
-#ifndef	POLY_IO_H
-#define	POLY_IO_H	"$Header: /cvsroot/clippoly/clippoly/poly_io.h,v 1.5 2005/02/28 17:21:12 klamer Exp $"
-
-//    nclip: a polygon clip library
-
-//    Copyright (C) 1993  Klamer Schutte
-
-//    klamer@mi.el.utwente.nl
-
-//    This library is free software; you can redistribute it and/or
-//    modify it under the terms of the GNU Library General Public
-//    License as published by the Free Software Foundation; either
-//    version 2 of the License, or (at your option) any later version.
-
-//    This library is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//    Library General Public License for more details.
-
-//    You should have received a copy of the GNU Library General Public
-//    License along with this library; if not, write to the Free
-//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-// $Log: poly_io.h,v $
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.1  1992/12/07  10:46:35  klamer
-// Initial revision
-//
-
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-#include	<iostream>
-
-#include <poly.h>
-
-#define	POLY_MAGIC	"PolyMagic"
-
-class Poly;
-class Point;
-class PolyNode;
-union	hvec3_t;
-
-Poly 	*read_poly( std::istream & );
-
-std::istream &operator>>(std::istream &, Point &);
-std::ostream	&operator<<(std::ostream &, const Poly &);
-std::ostream	&operator<<(std::ostream &, const PolyPList &);
-std::ostream	&operator<<(std::ostream &, const PolyNode &);
-std::ostream	&operator<<(std::ostream &, const Point &);
-std::ostream	&operator<<(std::ostream &, enum EdgeState);
-std::ostream	&operator<<(std::ostream &, enum LogicStates);
-std::ostream	&operator<<(std::ostream &, const hvec3_t &);
-
-#endif	/* POLY_IO_H */
+#ifndef	POLY_IO_H
+#define	POLY_IO_H
+
+//    nclip: a polygon clip library
+
+//    Copyright (C) 1993  Klamer Schutte
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.1  1992/12/07  10:46:35  klamer
+// Initial revision
+//
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include	<iostream>
+
+#include <poly.h>
+
+#define	POLY_MAGIC	"PolyMagic"
+
+class Poly;
+class Point;
+class PolyNode;
+union hvec3_t;
+
+Poly *read_poly (std::istream &);
+
+std::istream & operator>> (std::istream &, Point &);
+std::ostream & operator<< (std::ostream &, const Poly &);
+std::ostream & operator<< (std::ostream &, const PolyPList &);
+std::ostream & operator<< (std::ostream &, const PolyNode &);
+std::ostream & operator<< (std::ostream &, const Point &);
+std::ostream & operator<< (std::ostream &, enum EdgeState);
+std::ostream & operator<< (std::ostream &, enum LogicStates);
+std::ostream & operator<< (std::ostream &, const hvec3_t &);
+
+#endif /* POLY_IO_H */
--- clippoly-0.11.orig/posadder.cc
+++ clippoly-0.11/posadder.cc
@@ -1,77 +1,71 @@
-static const char rcs_id[] = "$Header: /cvsroot/clippoly/clippoly/posadder.cc,v 1.5 2005/02/28 17:21:12 klamer Exp $";
-
-//    nclip: a polygon clip library
-
-//    Copyright (C) 1993  University of Twente
-
-//    klamer@mi.el.utwente.nl
-
-//    This library is free software; you can redistribute it and/or
-//    modify it under the terms of the GNU Library General Public
-//    License as published by the Free Software Foundation; either
-//    version 2 of the License, or (at your option) any later version.
-
-//    This library is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//    Library General Public License for more details.
-
-//    You should have received a copy of the GNU Library General Public
-//    License along with this library; if not, write to the Free
-//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-// $Log: posadder.cc,v $
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.2  1994/01/04  12:55:37  klamer
-// *** empty log message ***
-//
-// Revision 1.1  1993/10/27  14:44:10  klamer
-// Initial revision
-//
-// Revision 1.1  1992/12/07  10:46:35  klamer
-// Initial revision
-//
-
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
-#include	<err.h>
-
-#include	"posadder.h"
-
-static const char h_rcs_id[] = POSADDER_H;
-
-void
-PosAdder::set(LogicStates boolean)
-{
-  if (val == TrueFalse)
-    return;
-  
-	switch(boolean)
-	{case UnKnown:
-		break;
-   case TrueFalse:
-		val = TrueFalse;
-		break;
-	case True:
-		if (val == False)
-			//error("Conflict in PosAdder::set (False, True)\n");
-		  val = TrueFalse;
-		else
-		  val = True;
-		break;
-	case False:
-		if (val == True)
-			//error("Conflict in PosAdder::set (True, False)\n");
-		  val = TrueFalse;
-		else
-		val = False;
-		break;
-	}
-}
-		
-	
+//    nclip: a polygon clip library
+
+//    Copyright (C) 1993  University of Twente
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.2  1994/01/04  12:55:37  klamer
+// *** empty log message ***
+//
+// Revision 1.1  1993/10/27  14:44:10  klamer
+// Initial revision
+//
+// Revision 1.1  1992/12/07  10:46:35  klamer
+// Initial revision
+//
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include	<error.h>
+
+#include	"posadder.h"
+
+void
+PosAdder::set (LogicStates boolean)
+{
+  if (val == TrueFalse)
+    return;
+
+  switch (boolean)
+    {
+    case UnKnown:
+      break;
+    case TrueFalse:
+      val = TrueFalse;
+      break;
+    case True:
+      if (val == False)
+	//error_at_line(0, 0, __FILE__, __LINE__, "Conflict in PosAdder::set (False, True)");
+	val = TrueFalse;
+      else
+	val = True;
+      break;
+    case False:
+      if (val == True)
+	//error_at_line(0, 0, __FILE__, __LINE__, "Conflict in PosAdder::set (True, False)");
+	val = TrueFalse;
+      else
+	val = False;
+      break;
+    }
+}
--- clippoly-0.11.orig/posadder.h
+++ clippoly-0.11/posadder.h
@@ -1,57 +1,59 @@
-#ifndef	POSADDER_H
-#define	POSADDER_H	"$Header: /cvsroot/clippoly/clippoly/posadder.h,v 1.5 2005/02/28 17:21:12 klamer Exp $"
-
-//    nclip: a polygon clip library
-
-//    Copyright (C) 1993  Klamer Schutte
-
-//    klamer@mi.el.utwente.nl
-
-//    This library is free software; you can redistribute it and/or
-//    modify it under the terms of the GNU Library General Public
-//    License as published by the Free Software Foundation; either
-//    version 2 of the License, or (at your option) any later version.
-
-//    This library is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//    Library General Public License for more details.
-
-//    You should have received a copy of the GNU Library General Public
-//    License along with this library; if not, write to the Free
-//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-// $Log: posadder.h,v $
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.1  1993/10/27  14:43:55  klamer
-// Initial revision
-//
-// Revision 1.1  1993/10/27  14:43:55  klamer
-// Initial revision
-//
-// Revision 1.1  1992/12/07  10:46:35  klamer
-// Initial revision
-//
-
-#ifdef __GNUG__
-#pragma interface
-#endif
-	
-enum LogicStates	{ UnKnown, True, False, TrueFalse };
-
-class PosAdder
-{
-	LogicStates		val;
-public:
-	PosAdder()
-		: val( UnKnown )
-		{ }
-	void			set( LogicStates boolean );
-	LogicStates		operator() () const
-					{ return val; }
-};
-
-#endif	/* POSADDER_H */
+#ifndef	POSADDER_H
+#define	POSADDER_H
+
+//    nclip: a polygon clip library
+
+//    Copyright (C) 1993  Klamer Schutte
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.1  1993/10/27  14:43:55  klamer
+// Initial revision
+//
+// Revision 1.1  1993/10/27  14:43:55  klamer
+// Initial revision
+//
+// Revision 1.1  1992/12/07  10:46:35  klamer
+// Initial revision
+//
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+enum LogicStates
+{ UnKnown, True, False, TrueFalse };
+
+class PosAdder
+{
+  LogicStates val;
+public:
+    PosAdder ():val (UnKnown)
+  {
+  }
+  void set (LogicStates boolean);
+  LogicStates operator () () const
+  {
+    return val;
+  }
+};
+
+#endif /* POSADDER_H */
--- clippoly-0.11.orig/primitives.cc
+++ clippoly-0.11/primitives.cc
@@ -1,92 +1,90 @@
-static const char rcs_id[] = "$Header: /cvsroot/clippoly/clippoly/primitives.cc,v 1.5 2005/02/28 17:21:12 klamer Exp $";
-
-//    nclip: a polygon clip library
-
-//    Copyright (C) 1993  University of Twente
-
-//    klamer@mi.el.utwente.nl
-
-//    This library is free software; you can redistribute it and/or
-//    modify it under the terms of the GNU Library General Public
-//    License as published by the Free Software Foundation; either
-//    version 2 of the License, or (at your option) any later version.
-
-//    This library is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//    Library General Public License for more details.
-
-//    You should have received a copy of the GNU Library General Public
-//    License along with this library; if not, write to the Free
-//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-// $Log: primitives.cc,v $
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.2  1994/01/04  12:55:37  klamer
-// Loosened assertion in angle() from angle < 2 pi to angle <= 2 pi.
-//
-// Revision 1.1  1993/10/27  14:44:13  klamer
-// Initial revision
-//
-// Revision 1.1  1992/12/07  10:46:35  klamer
-// Initial revision
-//
-
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
-#include	<cassert>
-#include	<cmath>
-
-#ifndef M_PI
-#define M_PI            3.14159265358979323846  /* pi */
-#endif
-
-#include	<err.h>
-
-#include	"primitives.h"
-
-static const char h_rcs_id[] = PRIMITIVES_H;
-
-const int PointList::def_len = 16;
-
-PointList::PointList( int nr )
-	: len( nr ), cur( 0 ), points( new Point[ nr ] )
-{
-	assert( nr > 0 );
-}
-
-PointList::~PointList()
-{
-	delete [] points;
-}
-
-void
-PointList::add( const Point &add )
-{
-	if (cur + 1 >= len)
-		fatal("PointList::add: Array too short (%d)\n", len);
-	
-	points[cur] = add;
-}
-
-double
-angle(const Point &p1, const Point &p2, const Point &p3)
-{
-	Point	d1 = p1 - p2, d2 = p3 - p2;
-	
-	double	res = atan( d2 ) - atan( d1 );
-	
-	if (res < 0)
-		res += M_PI * 2;
-
-	assert( res >= 0 );
-	assert( res <= M_PI * 2 );
-			
-	return res;
-}
-
+//    nclip: a polygon clip library
+
+//    Copyright (C) 1993  University of Twente
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.2  1994/01/04  12:55:37  klamer
+// Loosened assertion in angle() from angle < 2 pi to angle <= 2 pi.
+//
+// Revision 1.1  1993/10/27  14:44:13  klamer
+// Initial revision
+//
+// Revision 1.1  1992/12/07  10:46:35  klamer
+// Initial revision
+//
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+#include	<cassert>
+#include	<cmath>
+
+#ifndef M_PI
+#define M_PI            3.14159265358979323846	/* pi */
+#endif
+
+#include	<error.h>
+
+#include	"primitives.h"
+
+const int
+  PointList::def_len = 16;
+
+PointList::PointList (int nr):
+len (nr),
+cur (0),
+points (new Point[nr])
+{
+  assert (nr > 0);
+}
+
+PointList::~PointList ()
+{
+  delete[]points;
+}
+
+void
+PointList::add (const Point & add)
+{
+  if (cur + 1 >= len)
+    error_at_line (0, 0, __FILE__, __LINE__,
+		   "PointList::add: Array too short (%d)", len);
+
+  points[cur] = add;
+}
+
+double
+angle (const Point & p1, const Point & p2, const Point & p3)
+{
+  Point d1 = p1 - p2, d2 = p3 - p2;
+
+  double res = atan (d2) - atan (d1);
+
+  if (res < 0)
+    res += M_PI * 2;
+
+  assert (res >= 0);
+  assert (res <= M_PI * 2);
+
+  return res;
+}
--- clippoly-0.11.orig/primitives.h
+++ clippoly-0.11/primitives.h
@@ -1,205 +1,240 @@
-#ifndef	PRIMITIVES_H
-#define	PRIMITIVES_H	"$Header: /cvsroot/clippoly/clippoly/primitives.h,v 1.5 2005/02/28 17:21:12 klamer Exp $"
-
-//    nclip: a polygon clip library
-
-//    Copyright (C) 1993  Klamer Schutte
-
-//    klamer@mi.el.utwente.nl
-
-//    This library is free software; you can redistribute it and/or
-//    modify it under the terms of the GNU Library General Public
-//    License as published by the Free Software Foundation; either
-//    version 2 of the License, or (at your option) any later version.
-
-//    This library is distributed in the hope that it will be useful,
-//    but WITHOUT ANY WARRANTY; without even the implied warranty of
-//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//    Library General Public License for more details.
-
-//    You should have received a copy of the GNU Library General Public
-//    License along with this library; if not, write to the Free
-//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-// $Log: primitives.h,v $
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.1  1993/10/27  14:43:55  klamer
-// Initial revision
-//
-// Revision 1.1  1993/10/27  14:43:55  klamer
-// Initial revision
-//
-// Revision 1.1  1992/12/07  10:46:35  klamer
-// Initial revision
-//
-
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-#include <cmath>
-#include <cassert>
-#ifndef GRAPHMAT_INCLUDE
-#include	<graphmat.h>
-#endif
-
-class Point
-{
-	double	_x, _y;
-	
-public:
-	Point()
-		{ }
-	Point( double x, double y )
-		: _x(x), _y(y)
-		{ }
-	Point( const hvec2_t &h )
-		: _x(v_x(h)), _y(v_y(h))
-		{ }
-
-	double	x() const
-		{ return _x; }
-	double	&x()
-		{ return _x; }
-	double	y() const
-		{ return _y; }
-	double	&y()
-		{ return _y; }
-			
-	// operator hvec2_t();	// Does crash g++ 2.2.1 when used :-(
-	hvec2_t	hvec() const
-//		{ hvec2_t res; v_fill2( x(), y(), 1.0, &res ); return res; }
-		{ hvec2_t res; v_x(res) = x(); v_y(res) = y(); v_w(res) = 1;
-			return res; }
-	const Point &operator=( const hvec2_t &copy )
-		{ _x = v_x(copy); _y = v_y( copy); return *this; }
-	const Point &operator=( const Point &copy )
-		{ _x = copy.x(); _y = copy.y(); return *this; }
-};
-
-inline Point	
-operator+( const Point &p1, const Point &p2 )
-{
-	return Point( p1.x() + p2.x(), p1.y() + p2.y() );
-}
-	
-inline Point	
-operator-( const Point &p1, const Point &p2 )
-{
-	return Point( p1.x() - p2.x(), p1.y() - p2.y() );
-}
-
-inline double
-len( const Point p )
-{
-	return sqrt( p.x() * p.x() + p.y() * p.y() );
-}
- 
-inline Point	
-operator/( const Point &p, double div )
-{
-	return Point( p.x() / div, p.y() / div );
-}
-
-inline int
-operator==( const Point &p1, const Point &p2 )
-{
-	return (p1.x() == p2.x()) && (p1.y() == p2.y());
-}
-
-inline int
-operator!=( const Point &p1, const Point &p2 )
-{
-	return (p1.x() != p2.x()) || (p1.y() != p2.y());
-}
-
-inline int
-operator<( const Point &p1, const Point &p2 )
-{
-	return (p1.y() < p2.y()) || ((p1.y() == p2.y()) && (p1.x() < p2.x()));
-}
-
-inline int
-operator>( const Point &p1, const Point &p2 )
-{
-	return (p1.y() > p2.y()) || ((p1.y() == p2.y()) && (p1.x() > p2.x()));
-}
-
-double	angle( const Point &p1, const Point &p2, const Point &p3 );
-
-inline double
-atan( const Point &p )
-{
-	assert( (p.x() != 0) || (p.y() != 0) );
-	return atan2( p.y(), p.x() );
-}
-
-inline Point 
-point(const hvec3_t &p)
-{
-	hvec3_t	pn;
-	v_homo3( &p, &pn );
-	
-	return Point( v_x(pn), v_y(pn) );
-}
-
-class PointList
-{
-	friend class PointListIter;
-	
-	int	len, cur;
-	Point	*points;
-
-	static const int	def_len; //	= 16;
-	// Make copy constructor and assignment unusable
-	PointList( PointList &copy );
-	PointList &operator=( const PointList &copy );
-		
-public:
-	PointList( int nr = def_len );
-	~PointList();
-	
-	void	add( const Point &add );
-};
-
-class PointListIter
-{
-	const PointList	&pl;
-	int				cnt;
-	
-public:
-	PointListIter( const PointList &list )
-		: pl( list ), cnt( -1 )
-		{ }
-	
-	int	operator() ()
-		{ if (++cnt < pl.cur) return 1; else return 0; }
-	
-	const Point	&point() const
-		{ return pl.points[cnt]; }
-};
-
-class Edge
-{
-	Point	point1, point2;
-	// int		shared;
-	
-public:
-	Edge( const Point &p1, const Point &p2 ) //, int share = -1 )
-		: point1( p1 ), point2( p2 ) //, shared( share )
-		{ }
-	Point	middle() const
-		{ return (point1 + point2) / 2.0; }
-	// void	set_shared( int val )
-	//	{ shared = val; }
-	
-	const Point	&p1() const
-		{ return point1; } 
-	const Point 	&p2() const
-		{ return point2; }	
-};
-
-#endif	/* PRIMITIVES_H */
+#ifndef	PRIMITIVES_H
+#define	PRIMITIVES_H
+
+//    nclip: a polygon clip library
+
+//    Copyright (C) 1993  Klamer Schutte
+
+//    klamer@mi.el.utwente.nl
+
+//    This library is free software; you can redistribute it and/or
+//    modify it under the terms of the GNU Library General Public
+//    License as published by the Free Software Foundation; either
+//    version 2 of the License, or (at your option) any later version.
+
+//    This library is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//    Library General Public License for more details.
+
+//    You should have received a copy of the GNU Library General Public
+//    License along with this library; if not, write to the Free
+//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.1  1993/10/27  14:43:55  klamer
+// Initial revision
+//
+// Revision 1.1  1993/10/27  14:43:55  klamer
+// Initial revision
+//
+// Revision 1.1  1992/12/07  10:46:35  klamer
+// Initial revision
+//
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include <cmath>
+#include <cassert>
+#ifndef GRAPHMAT_INCLUDE
+#include	<graphmat.h>
+#endif
+
+class Point
+{
+  double _x, _y;
+
+public:
+    Point ()
+  {
+  }
+  Point (double x, double y):_x (x), _y (y)
+  {
+  }
+  Point (const hvec2_t & h):_x (v_x (h)), _y (v_y (h))
+  {
+  }
+
+  double x () const
+  {
+    return _x;
+  }
+  double &x ()
+  {
+    return _x;
+  }
+  double y () const
+  {
+    return _y;
+  }
+  double &y ()
+  {
+    return _y;
+  }
+
+  // operator hvec2_t();  // Does crash g++ 2.2.1 when used :-(
+  hvec2_t hvec () const
+//              { hvec2_t res; v_fill2( x(), y(), 1.0, &res ); return res; }
+  {
+    hvec2_t res;
+      v_x (res) = x ();
+      v_y (res) = y ();
+      v_w (res) = 1;
+      return res;
+  }
+  const Point & operator= (const hvec2_t & copy)
+  {
+    _x = v_x (copy);
+    _y = v_y (copy);
+    return *this;
+  }
+  const Point & operator= (const Point & copy)
+  {
+    _x = copy.x ();
+    _y = copy.y ();
+    return *this;
+  }
+};
+
+inline Point
+operator+ (const Point & p1, const Point & p2)
+{
+  return Point (p1.x () + p2.x (), p1.y () + p2.y ());
+}
+
+inline Point
+operator- (const Point & p1, const Point & p2)
+{
+  return Point (p1.x () - p2.x (), p1.y () - p2.y ());
+}
+
+inline double
+len (const Point p)
+{
+  return hypot (p.x (), p.y ());
+}
+
+inline Point
+operator/ (const Point & p, double div)
+{
+  return Point (p.x () / div, p.y () / div);
+}
+
+inline int
+operator== (const Point & p1, const Point & p2)
+{
+  return (p1.x () == p2.x ()) && (p1.y () == p2.y ());
+}
+
+inline int
+operator!= (const Point & p1, const Point & p2)
+{
+  return (p1.x () != p2.x ()) || (p1.y () != p2.y ());
+}
+
+inline int
+operator< (const Point & p1, const Point & p2)
+{
+  return (p1.y () < p2.y ()) || ((p1.y () == p2.y ()) && (p1.x () < p2.x ()));
+}
+
+inline int
+operator> (const Point & p1, const Point & p2)
+{
+  return (p1.y () > p2.y ()) || ((p1.y () == p2.y ()) && (p1.x () > p2.x ()));
+}
+
+double angle (const Point & p1, const Point & p2, const Point & p3);
+
+inline double
+atan (const Point & p)
+{
+  assert ((p.x () != 0) || (p.y () != 0));
+  return atan2 (p.y (), p.x ());
+}
+
+inline Point
+point (const hvec3_t & p)
+{
+  hvec3_t pn;
+  v_homo3 (&p, &pn);
+
+  return Point (v_x (pn), v_y (pn));
+}
+
+class PointList
+{
+  friend class PointListIter;
+
+  int len, cur;
+  Point *points;
+
+  static const int def_len;	//     = 16;
+  // Make copy constructor and assignment unusable
+    PointList (PointList & copy);
+    PointList & operator= (const PointList & copy);
+
+public:
+    PointList (int nr = def_len);
+   ~PointList ();
+
+  void add (const Point & add);
+};
+
+class PointListIter
+{
+  const PointList & pl;
+  int cnt;
+
+public:
+    PointListIter (const PointList & list):pl (list), cnt (-1)
+  {
+  }
+
+  int operator () ()
+  {
+    if (++cnt < pl.cur)
+      return 1;
+    else
+      return 0;
+  }
+
+  const Point & point () const
+  {
+    return pl.points[cnt];
+  }
+};
+
+class Edge
+{
+  Point point1, point2;
+  // int          shared;
+
+public:
+    Edge (const Point & p1, const Point & p2)	//, int share = -1 )
+  : point1 (p1), point2 (p2)	//, shared( share )
+  {
+  }
+  Point middle () const
+  {
+    return (point1 + point2) / 2.0;
+  }
+  // void set_shared( int val )
+  //      { shared = val; }
+
+  const Point & p1 () const
+  {
+    return point1;
+  }
+  const Point & p2 () const
+  {
+    return point2;
+  }
+};
+
+#endif /* PRIMITIVES_H */
--- clippoly-0.11.orig/set.h
+++ clippoly-0.11/set.h
@@ -1,240 +1,294 @@
-#ifndef	SET_H
-#define	SET_H	"$Header: /cvsroot/clippoly/clippoly/set.h,v 1.5 2005/02/28 17:21:12 klamer Exp $"
-
-// $Log: set.h,v $
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.3  1994/11/09  08:08:23  schutte
-// constness fixes.
-// Code cleanup.
-//
-// Revision 1.2  1994/01/04  12:55:37  klamer
-// Made default size 64 instead of 16.
-// Renamed len to _len.
-//
-// Revision 1.1  1993/10/27  14:43:58  klamer
-// Initial revision
-//
-// Revision 1.3  1993/10/27  14:28:05  klamer
-// Version as used in itool.
-//
-// Revision 1.2  1993/01/18  14:56:18  klamer
-// Spie version.
-//
-// Revision 1.1  1992/12/07  10:46:35  klamer
-// Initial revision
-//
-
-#ifdef __GNUG__
-#ifndef GEN_TEMPLATES
-#pragma interface
-#endif
-#endif
-#ifndef assert
-#include	<assert.h>
-#endif
-
-#ifdef sgi
-#ifdef __GNUG__
-#define	INLINE	inline
-#else
-#define	INLINE	// Nothing
-// The CC with Irix 5.2 is too stupid for these inline's
-#endif
-#else
-#define	INLINE	inline
-#endif
-
-template <class T> class SetIter;
-template <class T> class RSetIter;
-
-template <class T>
-class Set
-{
-	friend class	SetIter<T>;
-	
-	T			*data;
-	int			_len, used;
-	T			operator[](int cnt) const
-				{ return data[cnt]; }
-	void		operator=(const Set<T> &);	// Don't use it!
-	void		_resize();
-	
-public:
-	Set( int size = 64 )
-		: data( new T [size] ), _len(size), used(0)
-		{ }
-	~Set()
-		{	delete [] data; }
-	
-	int 		contains( T elem ) const 
-				{	return seek( elem ) >= 0; }
-	int			seek( T elem ) const
-				{	SetIter<T>	iter(*this);
-					while(iter())
-						if (iter.val() == elem)
-							return iter.cnt();
-					return -1;	}
-	void		add( T elem )
-				{	if (!contains(elem))
-					{	if (used + 1 >= _len)
-							_resize();
-						data[used] = elem;
-						used++; 	} }
-	void		del( T elem )
-			{	int	i = seek(elem);
-				if (i >= 0)
-				{	data[i] = data[used-1];
-					used--;	} }
-	int			empty() const
-				{	return used == 0; }
-	T			first()
-				{	assert(used > 0);
-					return data[0]; }
-	int			length() const
-				{	return used; }
-};
-
-template <class T> void
-Set<T>::_resize()
-{
-	T	*new_data = new T [_len * 2];
-	for(int i = 0; i < _len; i++)
-		new_data[i] = data[i];
-	delete [] data;
-	data = new_data;
-	_len *= 2;
-}
-
-template <class T>
-class SetIter
-{
-	int			_cnt;
-	const Set<T>	&_set;
-	const Set<T>	&set()
-					{ return _set; }
-				
-public:
-	SetIter( const Set<T> &set )
-		: _cnt(-1), _set(set)
-		{ }
-	
-	INLINE int			operator() ();
-#ifdef notdef
-				{	if (cnt() >= (_set.used-1))
-						return 0;
-					_cnt++;
-					return 1;	}
-#endif
-	inline T			val() const;
-#ifdef notdef
-				{ return _set[_cnt]; }
-#endif
-	int			cnt() const
-				{ return _cnt; }
-};
-	
-template <class T> INLINE int
-SetIter<T>::operator() ()
-{
-	if (cnt() >= (_set.used-1))
-		return 0;
-	_cnt++;
-	return 1;
-}
-
-template <class T> inline T
-  SetIter<T>::val() const
-{
-  return _set[_cnt];
-}
-
-
-template <class T>
-class RSet
-{
-	friend class	RSetIter<T>;
-	
-	T			*data;
-	int			_len, used;
-	T			&operator[](int cnt)
-				{ return data[cnt]; }
-	void		operator=(const RSet<T> &);	// Don't use it!
-	void		_resize();
-	
-public:
-	RSet( int size = 64 )
-		: data( new T [size] ), _len(size), used(0)
-		{ }
-	~RSet()
-		{	delete [] data; }
-	
-	int 		contains( const T &elem ) const 
-				{	return seek( elem ) >= 0; }
-	int			seek( const T &elem ) const
-				{	for(int i = 0; i < used; i++)
-						if (data[i] == elem)
-							return i;
-					return -1;	}
-	void		add( const T &elem )
-				{	if (!contains(elem))
-					{	if (used +1 >= _len)
-							_resize();
-						data[used] = elem;
-						used++; 	} }
-	int			length() const
-				{	return used; }
-	void		clear()
-			{	used = 0; }
-};
-
-template <class T> void
-RSet<T>::_resize()
-{
-	T	*new_data = new T [_len * 2];
-	for(int i = 0; i < _len; i++)
-		new_data[i] = data[i];
-	delete [] data;
-	data = new_data;
-	_len *= 2;
-}
-
-template <class T>
-class RSetIter
-{
-	int			_cnt;
-	const RSet<T>	&_set;
-	const RSet<T>	&set()
-					{ return _set; }
-				
-public:
-	RSetIter( const RSet<T> &set )
-		: _cnt(-1), _set(set)
-		{ }
-	
-	INLINE int			operator() ();
-#ifdef notdef
-				{	if (_cnt >= (_set.used-1))
-						return 0;
-					_cnt++;
-					return 1;	}
-#endif
-	const T			&val() const
-				{ return _set.data[_cnt]; }
-	int			cnt() const
-				{ return _cnt; }
-};
-
-template <class T> INLINE int
-  RSetIter<T>::operator() ()
-{       
-  if (_cnt >= (_set.used-1))
-    return 0;
-  _cnt++;
-  return 1;     
-}
-
-
-#endif	/* SET_H */
+#ifndef	SET_H
+#define	SET_H
+
+// Revision 1.6  2005/03/12 16:32:36  klamer
+// Changes to keep Visual C++ (vc98) silent while compiling.
+//
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.3  1994/11/09  08:08:23  schutte
+// constness fixes.
+// Code cleanup.
+//
+// Revision 1.2  1994/01/04  12:55:37  klamer
+// Made default size 64 instead of 16.
+// Renamed len to _len.
+//
+// Revision 1.1  1993/10/27  14:43:58  klamer
+// Initial revision
+//
+// Revision 1.3  1993/10/27  14:28:05  klamer
+// Version as used in itool.
+//
+// Revision 1.2  1993/01/18  14:56:18  klamer
+// Spie version.
+//
+// Revision 1.1  1992/12/07  10:46:35  klamer
+// Initial revision
+//
+
+#ifdef __GNUG__
+#ifndef GEN_TEMPLATES
+#pragma interface
+#endif
+#endif
+#ifndef assert
+#include	<assert.h>
+#endif
+
+#include <error.h>
+
+#ifdef sgi
+#ifdef __GNUG__
+#define	INLINE	inline
+#else
+#define	INLINE			// Nothing
+// The CC with Irix 5.2 is too stupid for these inline's
+#endif
+#else
+#define	INLINE	inline
+#endif
+
+template < class T > class SetIter;
+template < class T > class RSetIter;
+
+template < class T > class Set
+{
+  friend class SetIter < T >;
+
+  T *data;
+  int _len, used;
+  T operator[] (int cnt) const
+  {
+    return data[cnt];
+  }
+  void operator= (const Set < T > &)	// Don't use it!
+  {
+    error_at_line (1, 0, __FILE__, __LINE__, "This should not happen");
+  }
+  void _resize ();
+
+public:
+Set (int size = 64):data (new T[size]), _len (size), used (0)
+  {
+  }
+  ~Set ()
+  {
+    delete[]data;
+  }
+
+  int contains (T elem) const
+  {
+    return seek (elem) >= 0;
+  }
+  int seek (T elem) const
+  {
+    SetIter < T > iter (*this);
+    while (iter ())
+      if (iter.val () == elem)
+	return iter.cnt ();
+    return -1;
+  }
+  void add (T elem)
+  {
+    if (!contains (elem))
+      {
+	if (used + 1 >= _len)
+	  _resize ();
+	data[used] = elem;
+	used++;
+      }
+  }
+  void del (T elem)
+  {
+    int i = seek (elem);
+    if (i >= 0)
+      {
+	data[i] = data[used - 1];
+	used--;
+      }
+  }
+  int empty () const
+  {
+    return used == 0;
+  }
+  T first ()
+  {
+    assert (used > 0);
+    return data[0];
+  }
+  int length () const
+  {
+    return used;
+  }
+};
+
+template < class T > void Set < T >::_resize ()
+{
+  T *new_data = new T[_len * 2];
+  for (int i = 0; i < _len; i++)
+    new_data[i] = data[i];
+  delete[]data;
+  data = new_data;
+  _len *= 2;
+}
+
+template < class T > class SetIter
+{
+  int _cnt;
+  const Set < T > &_set;
+  const Set < T > &set ()
+  {
+    return _set;
+  }
+
+public:
+  SetIter (const Set < T > &set):_cnt (-1), _set (set)
+  {
+  }
+
+  INLINE int operator () ();
+#ifdef notdef
+  {
+    if (cnt () >= (_set.used - 1))
+      return 0;
+    _cnt++;
+    return 1;
+  }
+#endif
+  inline T val () const;
+#ifdef notdef
+  {
+    return _set[_cnt];
+  }
+#endif
+  int cnt () const
+  {
+    return _cnt;
+  }
+};
+
+template < class T > INLINE int SetIter < T >::operator () ()
+{
+  if (cnt () >= (_set.used - 1))
+    return 0;
+  _cnt++;
+  return 1;
+}
+
+template < class T > inline T SetIter < T >::val ()const
+{
+  return _set[_cnt];
+}
+
+
+template < class T > class RSet
+{
+  friend class RSetIter < T >;
+
+  T *data;
+  int _len, used;
+  T & operator[](int cnt)
+  { return data[cnt];
+  }
+  void operator= (const RSet < T > &)	// Don't use it!
+  {
+    error_at_line (1, 0, __FILE__, __LINE__, "This should not happen");
+  }
+  void _resize ();
+
+public:
+RSet (int size = 64):data (new T[size]), _len (size), used (0)
+  {
+  }
+  ~RSet ()
+  {
+    delete[]data;
+  }
+
+  int contains (const T & elem) const
+  {
+    return seek (elem) >= 0;
+  }
+  int seek (const T & elem) const
+  {
+    for (int i = 0; i < used; i++)
+      if (data[i] == elem)
+	return i;
+    return -1;
+  }
+  void add (const T & elem)
+  {
+    if (!contains (elem))
+      {
+	if (used + 1 >= _len)
+	  _resize ();
+	data[used] = elem;
+	used++;
+      }
+  }
+  int length () const
+  {
+    return used;
+  }
+  void clear ()
+  {
+    used = 0;
+  }
+};
+
+template < class T > void RSet < T >::_resize ()
+{
+  T *new_data = new T[_len * 2];
+  for (int i = 0; i < _len; i++)
+    new_data[i] = data[i];
+  delete[]data;
+  data = new_data;
+  _len *= 2;
+}
+
+template < class T > class RSetIter
+{
+  int _cnt;
+  const RSet < T > &_set;
+  const RSet < T > &set ()
+  {
+    return _set;
+  }
+
+public:
+  RSetIter (const RSet < T > &set):_cnt (-1), _set (set)
+  {
+  }
+
+  INLINE int operator () ();
+#ifdef notdef
+  {
+    if (_cnt >= (_set.used - 1))
+      return 0;
+    _cnt++;
+    return 1;
+  }
+#endif
+  const T & val () const
+  {
+    return _set.data[_cnt];
+  }
+  int cnt () const
+  {
+    return _cnt;
+  }
+};
+
+template < class T > INLINE int RSetIter < T >::operator () ()
+{
+  if (_cnt >= (_set.used - 1))
+    return 0;
+  _cnt++;
+  return 1;
+}
+
+
+#endif /* SET_H */
--- clippoly-0.11.orig/t1
+++ clippoly-0.11/t1
@@ -1,13 +1,13 @@
-    -6   -12
-    -5   -12
-    -5    12
-    -6    12
-     PolyMagic
-    -6.040000076293946e+00    -1.124363494873047e+01
-    -6.000000114440919e+00    -1.131199813842774e+01
-    -4.896273727416993e+00    -1.292799926757813e+01
-    -4.831999893188478e+00     1.292435287475586e+01
-    -5.938339347839356e+00     1.131199954986572e+01
-    -6.040000076293946e+00     1.113841079711914e+01
-     PolyMagic
-
+    -6   -12
+    -5   -12
+    -5    12
+    -6    12
+     PolyMagic
+    -6.040000076293946e+00    -1.124363494873047e+01
+    -6.000000114440919e+00    -1.131199813842774e+01
+    -4.896273727416993e+00    -1.292799926757813e+01
+    -4.831999893188478e+00     1.292435287475586e+01
+    -5.938339347839356e+00     1.131199954986572e+01
+    -6.040000076293946e+00     1.113841079711914e+01
+     PolyMagic
+
--- clippoly-0.11.orig/t1.out
+++ clippoly-0.11/t1.out
@@ -1,33 +1,33 @@
-a_min_b:
--6	12
--5.46626	12
--5.93834	11.312
--6	11.2067
-PolyMagic
--5.5301	-12
--6	-12
--6	-11.312
-PolyMagic
-b_min_a:
--5.46626	12
--4.832	12.9244
--4.89627	-12.928
--5.5301	-12
--5	-12
--5	12
-PolyMagic
--6	-11.312
--6	-11.312
--6.04	-11.2436
--6.04	11.1384
--6	11.2067
-PolyMagic
-a_and_b:
--5.46626	12
--5	12
--5	-12
--5.5301	-12
--6	-11.312
--6	11.2067
--5.93834	11.312
-PolyMagic
+a_min_b:
+-6	12
+-5.46626	12
+-5.93834	11.312
+-6	11.2067
+PolyMagic
+-5.5301	-12
+-6	-12
+-6	-11.312
+PolyMagic
+b_min_a:
+-5.46626	12
+-4.832	12.9244
+-4.89627	-12.928
+-5.5301	-12
+-5	-12
+-5	12
+PolyMagic
+-6	-11.312
+-6	-11.312
+-6.04	-11.2436
+-6.04	11.1384
+-6	11.2067
+PolyMagic
+a_and_b:
+-5.46626	12
+-5	12
+-5	-12
+-5.5301	-12
+-6	-11.312
+-6	11.2067
+-5.93834	11.312
+PolyMagic
--- clippoly-0.11.orig/t2
+++ clippoly-0.11/t2
@@ -1,74 +1,74 @@
-    -6   -12
-     6   -12
-     6    12
-    -6    12
-     PolyMagic
-    -8.277779693603517e+00    -4.847999343872072e+00
-    -7.927209968566896e+00    -6.464000473022463e+00
-    -7.448631401062013e+00    -8.079999694824220e+00
-    -7.248000259399415e+00    -8.623224029541017e+00
-    -6.817340011596681e+00    -9.696000823974611e+00
-    -6.040000076293946e+00    -1.124363494873047e+01
-    -6.000000114440919e+00    -1.131199813842774e+01
-    -4.896273727416993e+00    -1.292799926757813e+01
-    -4.831999893188478e+00    -1.301112533569336e+01
-    -3.623999710083009e+00    -1.425591827392578e+01
-    -3.230938072204591e+00    -1.454400039672852e+01
-    -2.415999526977540e+00    -1.511193252563477e+01
-    -1.207999343872071e+00    -1.563492370605469e+01
-     8.392333974427402e-07    -1.585918975830078e+01
-     1.207999114990233e+00    -1.580090118408203e+01
-     2.415999298095702e+00    -1.545498062133789e+01
-     3.623999481201171e+00    -1.479440475463867e+01
-     3.936564331054687e+00    -1.454400039672852e+01
-     4.831999664306640e+00    -1.378045440673828e+01
-     5.570999984741210e+00    -1.292799926757813e+01
-     6.039999847412108e+00    -1.232095504760742e+01
-     6.675385360717772e+00    -1.131199813842774e+01
-     7.248000030517577e+00    -1.023243118286133e+01
-     7.498455886840819e+00    -9.696000823974611e+00
-     8.123055343627929e+00    -8.079999694824220e+00
-     8.456000213623046e+00    -6.973386535644533e+00
-     8.602106933593749e+00    -6.464000473022463e+00
-     8.959420089721679e+00    -4.847999343872072e+00
-     9.205696945190429e+00    -3.232000122070314e+00
-     9.351813201904296e+00    -1.616000900268556e+00
-     9.404005889892577e+00     2.288818343743060e-07
-     9.364294891357421e+00     1.615999450683592e+00
-     9.230662231445312e+00     3.232000579833983e+00
-     8.996884231567382e+00     4.847999801635741e+00
-     8.652069931030272e+00     6.464000930786131e+00
-     8.456000213623046e+00     7.160383453369139e+00
-     8.183857803344726e+00     8.080000152587889e+00
-     7.569743041992187e+00     9.696000328063963e+00
-     7.248000030517577e+00     1.038719295501709e+01
-     6.757033233642577e+00     1.131199954986572e+01
-     6.039999847412108e+00     1.244501708984375e+01
-     5.662796859741210e+00     1.292799972534180e+01
-     4.831999664306640e+00     1.387382053375244e+01
-     4.028244857788085e+00     1.454399990081787e+01
-     3.623999481201171e+00     1.486033653259277e+01
-     2.415999298095702e+00     1.549386810302734e+01
-     1.207999114990233e+00     1.581515621185303e+01
-     8.392333974427402e-07     1.585061668395996e+01
-    -1.207999343872071e+00     1.560486721038818e+01
-    -2.415999526977540e+00     1.506131576538086e+01
-    -3.145139808654786e+00     1.454399990081787e+01
-    -3.623999710083009e+00     1.418689846038818e+01
-    -4.828847999572755e+00     1.292799972534180e+01
-    -4.831999893188478e+00     1.292435287475586e+01
-    -5.938339347839356e+00     1.131199954986572e+01
-    -6.040000076293946e+00     1.113841079711914e+01
-    -6.767523880004884e+00     9.696000328063963e+00
-    -7.248000259399415e+00     8.508264770507811e+00
-    -7.407690162658692e+00     8.080000152587889e+00
-    -7.895205612182618e+00     6.464000930786131e+00
-    -8.254174346923829e+00     4.847999801635741e+00
-    -8.456000442504884e+00     3.535133590698241e+00
-    -8.502920265197755e+00     3.232000579833983e+00
-    -8.654713745117188e+00     1.615999450683592e+00
-    -8.707243080139161e+00     2.288818343743060e-07
-    -8.662716979980470e+00    -1.616000900268556e+00
-    -8.519124145507813e+00    -3.232000122070314e+00
-    -8.456000442504884e+00    -3.652660140991213e+00
-     PolyMagic
+    -6   -12
+     6   -12
+     6    12
+    -6    12
+     PolyMagic
+    -8.277779693603517e+00    -4.847999343872072e+00
+    -7.927209968566896e+00    -6.464000473022463e+00
+    -7.448631401062013e+00    -8.079999694824220e+00
+    -7.248000259399415e+00    -8.623224029541017e+00
+    -6.817340011596681e+00    -9.696000823974611e+00
+    -6.040000076293946e+00    -1.124363494873047e+01
+    -6.000000114440919e+00    -1.131199813842774e+01
+    -4.896273727416993e+00    -1.292799926757813e+01
+    -4.831999893188478e+00    -1.301112533569336e+01
+    -3.623999710083009e+00    -1.425591827392578e+01
+    -3.230938072204591e+00    -1.454400039672852e+01
+    -2.415999526977540e+00    -1.511193252563477e+01
+    -1.207999343872071e+00    -1.563492370605469e+01
+     8.392333974427402e-07    -1.585918975830078e+01
+     1.207999114990233e+00    -1.580090118408203e+01
+     2.415999298095702e+00    -1.545498062133789e+01
+     3.623999481201171e+00    -1.479440475463867e+01
+     3.936564331054687e+00    -1.454400039672852e+01
+     4.831999664306640e+00    -1.378045440673828e+01
+     5.570999984741210e+00    -1.292799926757813e+01
+     6.039999847412108e+00    -1.232095504760742e+01
+     6.675385360717772e+00    -1.131199813842774e+01
+     7.248000030517577e+00    -1.023243118286133e+01
+     7.498455886840819e+00    -9.696000823974611e+00
+     8.123055343627929e+00    -8.079999694824220e+00
+     8.456000213623046e+00    -6.973386535644533e+00
+     8.602106933593749e+00    -6.464000473022463e+00
+     8.959420089721679e+00    -4.847999343872072e+00
+     9.205696945190429e+00    -3.232000122070314e+00
+     9.351813201904296e+00    -1.616000900268556e+00
+     9.404005889892577e+00     2.288818343743060e-07
+     9.364294891357421e+00     1.615999450683592e+00
+     9.230662231445312e+00     3.232000579833983e+00
+     8.996884231567382e+00     4.847999801635741e+00
+     8.652069931030272e+00     6.464000930786131e+00
+     8.456000213623046e+00     7.160383453369139e+00
+     8.183857803344726e+00     8.080000152587889e+00
+     7.569743041992187e+00     9.696000328063963e+00
+     7.248000030517577e+00     1.038719295501709e+01
+     6.757033233642577e+00     1.131199954986572e+01
+     6.039999847412108e+00     1.244501708984375e+01
+     5.662796859741210e+00     1.292799972534180e+01
+     4.831999664306640e+00     1.387382053375244e+01
+     4.028244857788085e+00     1.454399990081787e+01
+     3.623999481201171e+00     1.486033653259277e+01
+     2.415999298095702e+00     1.549386810302734e+01
+     1.207999114990233e+00     1.581515621185303e+01
+     8.392333974427402e-07     1.585061668395996e+01
+    -1.207999343872071e+00     1.560486721038818e+01
+    -2.415999526977540e+00     1.506131576538086e+01
+    -3.145139808654786e+00     1.454399990081787e+01
+    -3.623999710083009e+00     1.418689846038818e+01
+    -4.828847999572755e+00     1.292799972534180e+01
+    -4.831999893188478e+00     1.292435287475586e+01
+    -5.938339347839356e+00     1.131199954986572e+01
+    -6.040000076293946e+00     1.113841079711914e+01
+    -6.767523880004884e+00     9.696000328063963e+00
+    -7.248000259399415e+00     8.508264770507811e+00
+    -7.407690162658692e+00     8.080000152587889e+00
+    -7.895205612182618e+00     6.464000930786131e+00
+    -8.254174346923829e+00     4.847999801635741e+00
+    -8.456000442504884e+00     3.535133590698241e+00
+    -8.502920265197755e+00     3.232000579833983e+00
+    -8.654713745117188e+00     1.615999450683592e+00
+    -8.707243080139161e+00     2.288818343743060e-07
+    -8.662716979980470e+00    -1.616000900268556e+00
+    -8.519124145507813e+00    -3.232000122070314e+00
+    -8.456000442504884e+00    -3.652660140991213e+00
+     PolyMagic
--- clippoly-0.11.orig/t2.out
+++ clippoly-0.11/t2.out
@@ -1,95 +1,95 @@
-a_min_b:
--6	12
--5.46626	12
--5.93834	11.312
--6	11.2067
-PolyMagic
--5.5301	-12
--6	-12
--6	-11.312
-PolyMagic
-b_min_a:
--5.46626	12
--4.832	12.9244
--4.82885	12.928
--3.624	14.1869
--3.14514	14.544
--2.416	15.0613
--1.208	15.6049
-8.39233e-07	15.8506
-1.208	15.8152
-2.416	15.4939
-3.624	14.8603
-4.02824	14.544
-4.832	13.8738
-5.6628	12.928
-6.04	12.445
-6.75703	11.312
-7.248	10.3872
-7.56974	9.696
-8.18386	8.08
-8.456	7.16038
-8.65207	6.464
-8.99688	4.848
-9.23066	3.232
-9.36429	1.616
-9.40401	2.28882e-07
-9.35181	-1.616
-9.2057	-3.232
-8.95942	-4.848
-8.60211	-6.464
-8.456	-6.97339
-8.12306	-8.08
-7.49846	-9.696
-7.248	-10.2324
-6.67539	-11.312
-6.04	-12.321
-5.571	-12.928
-4.832	-13.7805
-3.93656	-14.544
-3.624	-14.7944
-2.416	-15.455
-1.208	-15.8009
-8.39233e-07	-15.8592
--1.208	-15.6349
--2.416	-15.1119
--3.23094	-14.544
--3.624	-14.2559
--4.832	-13.0111
--4.89627	-12.928
--5.5301	-12
-6	-12
-6	12
-PolyMagic
--6	-11.312
--6	-11.312
--6.04	-11.2436
--6.81734	-9.696
--7.248	-8.62322
--7.44863	-8.08
--7.92721	-6.464
--8.27778	-4.848
--8.456	-3.65266
--8.51912	-3.232
--8.66272	-1.616
--8.70724	2.28882e-07
--8.65471	1.616
--8.50292	3.232
--8.456	3.53513
--8.25417	4.848
--7.89521	6.464
--7.40769	8.08
--7.248	8.50826
--6.76752	9.696
--6.04	11.1384
--6	11.2067
-PolyMagic
-a_and_b:
--5.46626	12
-6	12
-6	-12
--5.5301	-12
--6	-11.312
--6	11.2067
--5.93834	11.312
-PolyMagic
+a_min_b:
+-6	12
+-5.46626	12
+-5.93834	11.312
+-6	11.2067
+PolyMagic
+-5.5301	-12
+-6	-12
+-6	-11.312
+PolyMagic
+b_min_a:
+-5.46626	12
+-4.832	12.9244
+-4.82885	12.928
+-3.624	14.1869
+-3.14514	14.544
+-2.416	15.0613
+-1.208	15.6049
+8.39233e-07	15.8506
+1.208	15.8152
+2.416	15.4939
+3.624	14.8603
+4.02824	14.544
+4.832	13.8738
+5.6628	12.928
+6.04	12.445
+6.75703	11.312
+7.248	10.3872
+7.56974	9.696
+8.18386	8.08
+8.456	7.16038
+8.65207	6.464
+8.99688	4.848
+9.23066	3.232
+9.36429	1.616
+9.40401	2.28882e-07
+9.35181	-1.616
+9.2057	-3.232
+8.95942	-4.848
+8.60211	-6.464
+8.456	-6.97339
+8.12306	-8.08
+7.49846	-9.696
+7.248	-10.2324
+6.67539	-11.312
+6.04	-12.321
+5.571	-12.928
+4.832	-13.7805
+3.93656	-14.544
+3.624	-14.7944
+2.416	-15.455
+1.208	-15.8009
+8.39233e-07	-15.8592
+-1.208	-15.6349
+-2.416	-15.1119
+-3.23094	-14.544
+-3.624	-14.2559
+-4.832	-13.0111
+-4.89627	-12.928
+-5.5301	-12
+6	-12
+6	12
+PolyMagic
+-6	-11.312
+-6	-11.312
+-6.04	-11.2436
+-6.81734	-9.696
+-7.248	-8.62322
+-7.44863	-8.08
+-7.92721	-6.464
+-8.27778	-4.848
+-8.456	-3.65266
+-8.51912	-3.232
+-8.66272	-1.616
+-8.70724	2.28882e-07
+-8.65471	1.616
+-8.50292	3.232
+-8.456	3.53513
+-8.25417	4.848
+-7.89521	6.464
+-7.40769	8.08
+-7.248	8.50826
+-6.76752	9.696
+-6.04	11.1384
+-6	11.2067
+PolyMagic
+a_and_b:
+-5.46626	12
+6	12
+6	-12
+-5.5301	-12
+-6	-11.312
+-6	11.2067
+-5.93834	11.312
+PolyMagic
--- clippoly-0.11.orig/templates.cc
+++ clippoly-0.11/templates.cc
@@ -1,17 +1,14 @@
-static const char rcs_id[] = "$Header: /cvsroot/clippoly/clippoly/templates.cc,v 1.5 2005/02/28 17:21:12 klamer Exp $";
-
-// $Log: templates.cc,v $
-// Revision 1.5  2005/02/28 17:21:12  klamer
-// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
-// Change use of (libg++) String to ANSI C++ string.
-//
-// Revision 1.1  1995/04/27  07:19:20  klamer
-// Initial revision
-//
-
-#include	"set.h"
-#include	"poly.h"
-
-template class SetIter<Poly *>;
-template class Set<Poly *>;
-template class  RSet<NodePEdge>;
+// Revision 1.5  2005/02/28 17:21:12  klamer
+// Changed to have g++ 3.2.3 run silently using g++ -ansi -pedantic -Wall -Wno-unused -Wno-reorder.
+// Change use of (libg++) String to ANSI C++ string.
+//
+// Revision 1.1  1995/04/27  07:19:20  klamer
+// Initial revision
+//
+
+#include	"set.h"
+#include	"poly.h"
+
+template class SetIter < Poly * >;
+template class Set < Poly * >;
+template class RSet < NodePEdge >;
--- /dev/null
+++ clippoly-0.11/test0
@@ -0,0 +1,7 @@
+#!/bin/sh -f
+
+set -e
+
+cd ${srcdir:=.}
+
+./clippolytest < in_file | diff --ignore-space-change out_file.dist -
--- /dev/null
+++ clippoly-0.11/test1
@@ -0,0 +1,7 @@
+#!/bin/sh -f
+
+set -e
+
+cd ${srcdir:=.}
+
+./clippolytest < t1 | diff --ignore-space-change t1.out -
--- /dev/null
+++ clippoly-0.11/test2
@@ -0,0 +1,7 @@
+#!/bin/sh -f
+
+set -e
+
+cd ${srcdir:=.}
+
+./clippolytest < t2 | diff --ignore-space-change t2.out -
--- /dev/null
+++ clippoly-0.11/version.c
@@ -0,0 +1,4 @@
+// include unique non-C++ symbol for ease of ./configure tests
+#include "config.h"
+#include "version.h"
+const char clippoly_version[] = PACKAGE_VERSION;
--- /dev/null
+++ clippoly-0.11/version.h
@@ -0,0 +1 @@
+extern const char clippoly_version[];
