Description: Undocumented upstream changes
 This patch has been created by dpkg-source during the package build
 but it might have accumulated changes from several uploads. Please
 check the changelog to (hopefully) learn more on those changes.

--- /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;
--- clippoly-0.11.orig/primitives.h
+++ clippoly-0.11/primitives.h
@@ -1,205 +1,204 @@
-#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/primitives.cc
+++ clippoly-0.11/primitives.cc
@@ -1,92 +1,88 @@
-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/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/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/poly.cc
+++ clippoly-0.11/poly.cc
@@ -1,585 +1,580 @@
-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/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/graphadd.h
+++ clippoly-0.11/graphadd.h
@@ -1,112 +1,110 @@
-/*
- *    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/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/poly.h
+++ clippoly-0.11/poly.h
@@ -1,318 +1,322 @@
-//    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/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
--- /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 -
--- clippoly-0.11.orig/posadder.h
+++ clippoly-0.11/posadder.h
@@ -1,57 +1,56 @@
-#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 */
--- /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/version.h
@@ -0,0 +1 @@
+extern const char clippoly_version[];
--- clippoly-0.11.orig/poly_io.cc
+++ clippoly-0.11/poly_io.cc
@@ -1,191 +1,187 @@
-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/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/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
--- /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 -
--- 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/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>;
--- 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
--- 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
--- /dev/null
+++ clippoly-0.11/configure.ac
@@ -0,0 +1,35 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.67])
+AC_INIT([polygon clipping library],[0.11],[klamer@mi.el.utwente.nl],[clippoly],[//http://clippoly.sourceforge.net])
+AM_INIT_AUTOMAKE([subdir-objects foreign])
+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
+
+LT_INIT
+
+# Checks for header files.
+AC_CHECK_HEADERS([float.h malloc.h stdlib.h string.h])
+
+AC_CONFIG_MACRO_DIR([m4])
+
+AC_LANG([C++])
+
+# 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_CHECK_FUNCS([hypot])
+
+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 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
--- 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/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
+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
--- clippoly-0.11.orig/nclip.cc
+++ clippoly-0.11/nclip.cc
@@ -1,673 +1,670 @@
-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/graphmat.h
+++ clippoly-0.11/graphmat.h
@@ -1,328 +1,330 @@
-/*
- *    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
--- /dev/null
+++ clippoly-0.11/clippolytest.cc
@@ -0,0 +1,60 @@
+//    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;
+}
--- clippoly-0.11.orig/graphmat++.h
+++ clippoly-0.11/graphmat++.h
@@ -1,232 +1,231 @@
-//    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
+
--- /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 -
--- 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/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/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
--- /dev/null
+++ clippoly-0.11/Makefile.am
@@ -0,0 +1,37 @@
+ACLOCAL_AMFLAGS = -I m4
+
+AM_CPPFLAGS = -I. -DGEN_TEMPLATES
+AM_CXXFLAGS = -Wall
+AM_CFLAGS = -Wall
+
+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 = autogen.sh 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-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/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.
+
--- clippoly-0.11.orig/set.h
+++ clippoly-0.11/set.h
@@ -1,240 +1,246 @@
-#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/graphadd.cc
+++ clippoly-0.11/graphadd.cc
@@ -1,450 +1,445 @@
-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/posadder.cc
+++ clippoly-0.11/posadder.cc
@@ -1,77 +1,72 @@
-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/graphmat.c
+++ clippoly-0.11/graphmat.c
@@ -1,1665 +1,1661 @@
-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/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/nclip.h
+++ clippoly-0.11/nclip.h
@@ -1,66 +1,65 @@
-//    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 */
