debian/0000775000000000000000000000000012206225076007172 5ustar debian/source/0000775000000000000000000000000012206160236010466 5ustar debian/source/format0000664000000000000000000000001411730741335011702 0ustar 3.0 (quilt) debian/changelog0000664000000000000000000000154012206225007011036 0ustar clippoly (0.11-4) unstable; urgency=low * flush debian/rules standard dh target phony declarations (closes: #720692) * support multiarch -- Barak A. Pearlmutter Sat, 24 Aug 2013 22:47:51 +0100 clippoly (0.11-3) unstable; urgency=low * bump policy version * insert m4 doorstop * dh9 * multilib support * change priority from extra to optional * create and count rely upon m4/doorstop -- Barak A. Pearlmutter Mon, 16 Apr 2012 20:07:40 +0100 clippoly (0.11-2) unstable; urgency=low * fix typo in debian/control * work around quilt patch representation restriction issue -- Barak A. Pearlmutter Thu, 18 Aug 2011 09:27:24 +0200 clippoly (0.11-1) unstable; urgency=low * Initial release (Closes: #638013) -- Barak A. Pearlmutter Wed, 29 Jun 2011 15:21:36 +0200 debian/copyright0000664000000000000000000000272512206160243011125 0ustar This work was packaged for Debian by: Barak A. Pearlmutter on Wed, 29 Jun 2011 15:21:36 +0200 It was downloaded from: http://clippoly.sourceforge.net imported history to git with: git cvsimport -v -C clippoly -k -u -a clippoly -d :pserver:anonymous@clippoly.cvs.sourceforge.net:/cvsroot/clippoly other version to consider: wget --mirror --no-parent http://clippoly.sourceforge.net/Gregg.Leichtman Upstream Author: Klamer Schutte Copyright: Copyright (C) 1993 Klamer Schutte License: This package is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This package 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 Lesser General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . On Debian systems, the complete text of the GNU Lesser General Public License can be found in "/usr/share/common-licenses/LGPL-2". The Debian packaging is: Copyright (C) 2011 Barak A. Pearlmutter and is placed in the public domain. debian/control0000664000000000000000000000210512206224721010567 0ustar Source: clippoly Section: libs Priority: optional Maintainer: Barak A. Pearlmutter Build-Depends: debhelper (>= 9), dh-autoreconf Build-Conflicts: autoconf2.13, automake1.4 Standards-Version: 3.9.4 Homepage: http://clippoly.sourceforge.net Vcs-Git: git://git.debian.org/git/collab-maint/clippoly.git Vcs-Browser: http://git.debian.org/?p=collab-maint/clippoly.git Package: libclippoly0 Architecture: any Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${shlibs:Depends}, ${misc:Depends} Description: polygon clipping routines, runtime library Robust routines for clipping polygons against each other: finding unions and intersections and differences of polygonal regions. Runtime library. Package: libclippoly-dev Section: libdevel Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends}, libclippoly0 (= ${binary:Version}) Description: polygon clipping routines, development library Robust routines for clipping polygons against each other: finding unions and intersections and differences of polygonal regions. Development library. debian/libclippoly-dev.install0000664000000000000000000000007412206160243013653 0ustar usr/include/clippoly/*.h usr/lib/*/lib*.so usr/lib/*/lib*.a debian/libclippoly-dev.manpages0000664000000000000000000000004011730741335014001 0ustar debian/tmp/usr/share/man/man*/* debian/libclippoly0.install0000664000000000000000000000002412206160243013152 0ustar usr/lib/*/lib*.so.* debian/watch0000664000000000000000000000013311730741335010222 0ustar version=3 opts="uversionmangle=s/^pl/0./" \ http://sf.net/clippoly/clippoly-(.*)\.tar\.gz debian/compat0000664000000000000000000000000212206160243010362 0ustar 9 debian/libclippoly-dev.docs0000664000000000000000000000001711730741335013142 0ustar README CLASSES debian/patches/0000755000000000000000000000000012206225076010617 5ustar debian/patches/debian-changes0000644000000000000000000147333112206225076013406 0ustar Description: TODO: Put a short summary on the line above and replace this paragraph with a longer explanation of this change. Complete the meta-information with other relevant fields (see below for details). To make it easier, the information below has been extracted from the changelog. Adjust it or drop it. . clippoly (0.11-4) unstable; urgency=low . * flush debian/rules standard dh target phony declarations (closes: #720692) * support multiarch Author: Barak A. Pearlmutter Bug-Debian: http://bugs.debian.org/720692 --- The information above should follow the Patch Tagging Guidelines, please checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here are templates for supplementary fields that you might want to add: Origin: , Bug: Bug-Debian: http://bugs.debian.org/ Bug-Ubuntu: https://launchpad.net/bugs/ Forwarded: Reviewed-By: Last-Update: --- clippoly-0.11.orig/case1 +++ clippoly-0.11/case1 @@ -1,14 +1,14 @@ - 223 686 - 233 230 - 673 228 - 633 436 - 357 302 - 351 448 - 487 448 - 471 692 - PolyMagic - 397 604 - 397 372 - 723 374 - 723 608 - PolyMagic + 223 686 + 233 230 + 673 228 + 633 436 + 357 302 + 351 448 + 487 448 + 471 692 + PolyMagic + 397 604 + 397 372 + 723 374 + 723 608 + PolyMagic --- clippoly-0.11.orig/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/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; -template class Set; -template class RSet; +// 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; +template class Set; +template class RSet; --- 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 -.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 +.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/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/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/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 - -#include - -#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 + +#include + +#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 */ --- /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/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 -#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 +#endif + +#ifdef __GNUG__ +#pragma interface +#endif + +inline hvec2_t +operator-( const hvec2_t &h ) +{ + hvec2_t ret; + + v_fill2(-v_x(h),-v_y(h),v_w(h), &ret); + + return ret; +} + +inline hvec2_t +operator-( const hvec2_t &l, const hvec2_t &r ) +{ + hvec2_t ret; + + vv_sub2( &l, &r, &ret ); + + return ret; +} + +inline hvec2_t +operator+( const hvec2_t &l, const hvec2_t &r ) +{ + hvec2_t ret; + + vv_add2( &l, &r, &ret ); + + return ret; +} + +inline hvec2_t +operator*( const hmat2_t &m, const hvec2_t &v ) +{ + hvec2_t ret; + + mv_mul2( &m, &v, &ret ); + + return ret; +} + +inline hvec2_t +operator*( double s, const hvec2_t &v ) +{ + hvec2_t ret; + + sv_mul2( s, &v, &ret ); + + return ret; +} + +inline hvec2_t +operator/( const hvec2_t &v, double div ) +{ + hvec2_t ret; + + sv_mul2( 1.0/div, &v, &ret ); + + return ret; +} + +inline hvec2_t const & +operator+=( hvec2_t &v, const hvec2_t &add ) +{ + vv_add2( &v, &add, &v ); + + return v; +} + +inline hvec2_t const & +operator-=( hvec2_t &v, const hvec2_t &sub ) +{ + vv_sub2( &v, &sub, &v ); + + return v; +} + +inline hvec2_t const & +operator*=( hvec2_t &v, double mul ) +{ + sv_mul2( mul, &v, &v ); + + return v; +} + +inline hvec2_t const & +operator/=( hvec2_t &v, double div ) +{ + sv_mul2( 1.0/div, &v, &v ); + + return v; +} + +inline double +len( const hvec2_t &v ) +{ + return v_len2( &v ); +} + +inline hvec3_t +operator-( const hvec3_t &h ) +{ + hvec3_t ret; + + v_fill3(-v_x(h),-v_y(h), -v_z(h), v_w(h), &ret); + + return ret; +} + +inline hmat3_t +operator*( const hmat3_t &l, const hmat3_t &r ) +{ + hmat3_t res; + + mm_mul3(&l, &r, &res); + + return res; +} + +inline hvec3_t +operator*( const hmat3_t &m, const hvec3_t &v ) +{ + hvec3_t res; + + mv_mul3(&m, &v, &res); + + return res; +} + +inline hvec3_t +operator-( const hvec3_t &l, const hvec3_t &r ) +{ + hvec3_t res; + + vv_sub3( &l, &r, &res ); + + return res; +} + +inline hvec3_t +operator*( const hvec3_t &v, double s ) +{ + hvec3_t ret; + + sv_mul3( s, &v, &ret ); + + return ret; +} + + +inline hvec3_t +operator*( double s, const hvec3_t &v ) +{ + hvec3_t ret; + + sv_mul3( s, &v, &ret ); + + return ret; +} + +inline hvec3_t +operator+( const hvec3_t &l, const hvec3_t &r ) +{ + hvec3_t ret; + + vv_add3( &l, &r, &ret ); + + return ret; +} + +inline hvec3_t const & +operator-=( hvec3_t &v, const hvec3_t &sub ) +{ + vv_sub3( &v, &sub, &v ); + + return v; +} + +#endif + --- clippoly-0.11.orig/graphmat.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 - -#include - -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 + +#include + +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/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/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 */ --- /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/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 --- /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. + + + Copyright (C) + + 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. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! --- 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 -#include -#include -#else -#ifndef FILE -#include -#endif -#ifndef __malloc_h -#include -#endif -#ifndef __math_h -#include -#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 +#include +#include +#else +#ifndef FILE +#include +#endif +#ifndef __malloc_h +#include +#endif +#ifndef __math_h +#include +#endif +#endif + + +/****** DEFINES ******/ + +/* macro's for accessing the data elements of a vector or a matrix */ +#define m_elem(mat, i, j) ((mat).m[(i)][(j)]) +#define v_elem(vec, i) ((vec).a[(int)(i)]) +#define v_x(vec) ((vec).s.x) +#define v_y(vec) ((vec).s.y) +#define v_z(vec) ((vec).s.z) +#define v_w(vec) ((vec).s.w) + +/* +#define gm_NEW(type, ptr, func) \ + (((gm_dummy = malloc(sizeof(type))) == NULL) ? \ + ((type *)gm_error(NOMEM, func)) : \ + (type *)gm_dummy) +*/ + +typedef enum +{ + DIV0, NOMEM, MATSING +} gm_error_t; + +#ifdef __cplusplus +extern "C" void gm_error( int, const char * ); +#ifdef __GNUG__ +#pragma interface +#endif + +inline void * +gm_alloc( /*const*/ void *ptr, const char *func, int len ) +{ + if (ptr != 0) + return ptr; + else + { + void *gm_dummy; + + if ((gm_dummy = malloc(len)) == NULL) + return gm_error(NOMEM,func), (void *)0; + else + return gm_dummy; + } +} +#define gm_ALLOC(type, ptr, func) ((type *) \ + gm_alloc(ptr, func, sizeof(type)) +#else +/****** Globals ******/ +char *gm_dummy; /* used for memory allocation in gm_ALLOC() */ + +/* check if ptr is NULL, if so then allocate memory else return ptr */ +#define gm_ALLOC(type, ptr, func) (((ptr) == NULL) ? \ + ((gm_dummy = (char *)malloc(sizeof(type))) == NULL) ? \ + (gm_error(NOMEM, func), (type *)NULL) : \ + (type *)gm_dummy : (ptr)) +#endif + +/* if ptr is NULL then deallocate used space pointed by ptr */ +#define gm_FREE(ptr) if((ptr) != NULL) free((char *)(ptr)) + + +/* divide num by div if div != 0 else gm_error() */ +#define gm_DIV(num, div, func) (((div) != 0.0) ? ((num) / (div)) : gm_error(DIV0, (func))) + + +/****** Level 1 : data definition ******/ +typedef union hvec2_t +{ + double a[3]; + struct hvec2_s + { + double x, y, w; + } s; +} hvec2_t; + + +typedef union hvec3_t +{ + double a[4]; + struct hvec3_s + { + double x, y, z, w; + } s; +} hvec3_t; + + +typedef struct hmat2_t +{ + double m[3][3]; +} hmat2_t; + + +typedef struct hmat3_t +{ + double m[4][4]; +} hmat3_t; + + +typedef enum +{ + X_AXIS, Y_AXIS, Z_AXIS +} b_axis; + + +/****** Level 2 : Data initialisation ******/ +#define m_free2(matrix) gm_FREE(matrix) +#define v_free2(vector) gm_FREE(vector) +#define m_free3(matrix) gm_FREE(matrix) +#define v_free3(vector) gm_FREE(vector) + +#ifndef __cplusplus +#define m_alloc2(m_result) gm_ALLOC(hmat2_t, (m_result), "m_alloc2()") +#define v_alloc2(v_result) gm_ALLOC(hvec2_t, (v_result), "v_alloc2()") + +#define m_alloc3(m_result) gm_ALLOC(hmat3_t, (m_result), "m_alloc3()") +#define v_alloc3(v_result) gm_ALLOC(hvec3_t, (v_result), "v_alloc3()") +#else +inline void * +Alloc(unsigned int x ) +{ + void *res; + + res = malloc(x); + if (res == 0) + gm_error(NOMEM,"Alloc"); + + return res; +} + + +inline hmat2_t * +m_alloc2(hmat2_t *r) +{ + if (r) + return r; + else + return (hmat2_t *) Alloc(sizeof(hmat2_t)); +} + +inline hmat3_t * +m_alloc3(hmat3_t *r) +{ + if (r) + return r; + else + return (hmat3_t *) Alloc(sizeof(hmat3_t)); +} + +inline hvec2_t * +v_alloc2(hvec2_t *r) +{ + if (r) + return r; + else + return (hvec2_t *) Alloc(sizeof(hvec2_t)); +} + +inline hvec3_t * +v_alloc3(hvec3_t *r) +{ + if (r) + return r; + else + return (hvec3_t *) Alloc(sizeof(hvec3_t)); +} +#endif + +/****** FUNCTION DEFINITIONS ******/ +#if defined(__STDC__) || defined(__cplusplus) +# define P_(s) s +#else +# define P_(s) () +#endif + +#ifdef __cplusplus +extern "C" { +#define C__ } +#else +#define C__ +#endif + +hmat2_t *m_cpy2 P_((const hmat2_t *m_source, hmat2_t *m_result)); +hmat2_t *m_unity2 P_((hmat2_t *m_result)); +hvec2_t *v_cpy2 P_((const hvec2_t *v_source, hvec2_t *v_result)); +hvec2_t *v_fill2 P_((double x, double y, double w, hvec2_t *v_result)); +hvec2_t *v_unity2 P_((b_axis axis, hvec2_t *v_result)); +hvec2_t *v_zero2 P_((hvec2_t *v_result)); +hmat3_t *m_cpy3 P_((const hmat3_t *m_source, hmat3_t *m_result)); +hmat3_t *m_unity3 P_((hmat3_t *m_result)); +hvec3_t *v_cpy3 P_((const hvec3_t *v_source, hvec3_t *v_result)); +hvec3_t *v_fill3 P_((double x, double y, double z, double w, hvec3_t *v_result)); +hvec3_t *v_unity3 P_((b_axis axis, hvec3_t *v_result)); +hvec3_t *v_zero3 P_((hvec3_t *v_result)); +double m_det2 P_((const hmat2_t *matrix)); +double v_len2 P_((const hvec2_t *vector)); +double vtmv_mul2 P_((const hvec2_t *vector, const hmat2_t *matrix)); +double vv_inprod2 P_((const hvec2_t *vectorA, const hvec2_t *vectorB)); +hmat2_t *m_inv2 P_((const hmat2_t *matrix, hmat2_t *m_result)); +hmat2_t *m_tra2 P_((const hmat2_t *matrix, hmat2_t *m_result)); +hmat2_t *mm_add2 P_((const hmat2_t *matrixA, const hmat2_t *matrixB, hmat2_t *m_result)); +hmat2_t *mm_mul2 P_((const hmat2_t *matrixA, const hmat2_t *matrixB, hmat2_t *m_result)); +hmat2_t *mm_sub2 P_((const hmat2_t *matrixA, const hmat2_t *matrixB, hmat2_t *m_result)); +hmat2_t *mtmm_mul2 P_((const hmat2_t *matrixA, const hmat2_t *matrixB, hmat2_t *m_result)); +hmat2_t *sm_mul2 P_((double scalar, const hmat2_t *matrix, hmat2_t *m_result)); +hmat2_t *vvt_mul2 P_((const hvec2_t *vectorA, const hvec2_t *vectorB, hmat2_t *m_result)); +hvec2_t *mv_mul2 P_((const hmat2_t *matrix, const hvec2_t *vector, hvec2_t *v_result)); +hvec2_t *sv_mul2 P_((double scalar, const hvec2_t *vector, hvec2_t *v_result)); +hvec2_t *v_homo2 P_((const hvec2_t *vector, hvec2_t *v_result)); +hvec2_t *v_norm2 P_((const hvec2_t *vector, hvec2_t *v_result)); +hvec2_t *vv_add2 P_((const hvec2_t *vectorA, const hvec2_t *vectorB, hvec2_t *v_result)); +hvec2_t *vv_sub2 P_((const hvec2_t *vectorA, const hvec2_t *vectorB, hvec2_t *v_result)); +double m_det3 P_((const hmat3_t *matrix)); +double v_len3 P_((const hvec3_t *vector)); +double vtmv_mul3 P_((const hvec3_t *vector, const hmat3_t *matrix)); +double vv_inprod3 P_((const hvec3_t *vectorA, const hvec3_t *vectorB)); +hmat3_t *m_inv3 P_((const hmat3_t *matrix, hmat3_t *m_result)); +hmat3_t *m_tra3 P_((const hmat3_t *matrix, hmat3_t *m_result)); +hmat3_t *mm_add3 P_((const hmat3_t *matrixA, const hmat3_t *matrixB, hmat3_t *m_result)); +hmat3_t *mm_mul3 P_((const hmat3_t *matrixA, const hmat3_t *matrixB, hmat3_t *m_result)); +hmat3_t *mm_sub3 P_((const hmat3_t *matrixA, const hmat3_t *matrixB, hmat3_t *m_result)); +hmat3_t *mtmm_mul3 P_((const hmat3_t *matrixA, const hmat3_t *matrixB, hmat3_t *m_result)); +hmat3_t *sm_mul3 P_((double scalar, const hmat3_t *matrix, hmat3_t *m_result)); +hvec3_t *mv_mul3 P_((const hmat3_t *matrix, const hvec3_t *vector, hvec3_t *v_result)); +hvec3_t *sv_mul3 P_((double scalar, const hvec3_t *vector, hvec3_t *v_result)); +hvec3_t *v_homo3 P_((const hvec3_t *vector, hvec3_t *v_result)); +hvec3_t *v_norm3 P_((const hvec3_t *vector, hvec3_t *v_result)); +hvec3_t *vv_add3 P_((const hvec3_t *vectorA, const hvec3_t *vectorB, hvec3_t *v_result)); +hvec3_t *vv_cross3 P_((const hvec3_t *vectorA, const hvec3_t *vectorB, hvec3_t *v_result)); +hvec3_t *vv_sub3 P_((const hvec3_t *vectorA, const hvec3_t *vectorB, hvec3_t *v_result)); +hmat3_t *vvt_mul3 P_((const hvec3_t *vectorA, const hvec3_t *vectorB, hmat3_t *m_result)); +hmat2_t *miraxis2 P_((b_axis axis, hmat2_t *m_result)); +hmat2_t *mirorig2 P_((hmat2_t *m_result)); +hmat2_t *rot2 P_((double rotation, hmat2_t *m_result)); +hmat2_t *scaorig2 P_((double scale, hmat2_t *m_result)); +hmat2_t *scaxis2 P_((double scale, b_axis axis, hmat2_t *m_result)); +hmat2_t *transl2 P_((const hvec2_t *translation, hmat2_t *m_result)); +hmat3_t *miraxis3 P_((b_axis axis, hmat3_t *m_result)); +hmat3_t *mirorig3 P_((hmat3_t *m_result)); +hmat3_t *mirplane3 P_((b_axis plane, hmat3_t *m_result)); +hmat3_t *prjorthaxis P_((b_axis axis, hmat3_t *m_result)); +hmat3_t *prjpersaxis P_((b_axis axis, hmat3_t *m_result)); +hmat3_t *rot3 P_((double rotation, b_axis axis, hmat3_t *m_result)); +hmat3_t *scaorig3 P_((double scale, hmat3_t *m_result)); +hmat3_t *scaplane3 P_((double scale, b_axis plane, hmat3_t *m_result)); +hmat3_t *scaxis3 P_((double scale, b_axis axis, hmat3_t *m_result)); +hmat3_t *transl3 P_((const hvec3_t *translation, hmat3_t *m_result)); + +C__ +#undef C__ +#undef P_ +#endif --- clippoly-0.11.orig/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 -.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 +.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 --- /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/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 - -#ifndef PRIMITIVES_H -#include -#endif -#ifndef SET_H -#include -#endif -#ifndef POSADDER_H -#include -#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 © ); // Don't use - PolyNode( const PolyNode ©, 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; - friend class RSet; - 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 PolyNodePList; -typedef SetIter PolyNodePListIter; -typedef RSet NodePEdgeList; -typedef RSetIter NodePEdgeListIter; - -enum Orientation { ClockWise, CounterClockWise }; - -class Poly -{ -private: - friend class PolyIter; - friend class DirPolyIter; - - PolyNode *list, *prev; - Poly &operator=( const Poly © ); // Don't use it! - -public: - Poly( const Poly © ) - : 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 PolyPList; -typedef SetIter 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 + +#ifndef PRIMITIVES_H +#include +#endif +#ifndef SET_H +#include +#endif +#ifndef POSADDER_H +#include +#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 © ); // Don't use + PolyNode( const PolyNode ©, 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; + friend class RSet; + 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 PolyNodePList; +typedef SetIter PolyNodePListIter; +typedef RSet NodePEdgeList; +typedef RSetIter NodePEdgeListIter; + +enum Orientation { ClockWise, CounterClockWise }; + +class Poly +{ +private: + friend class PolyIter; + friend class DirPolyIter; + + PolyNode *list, *prev; + Poly &operator=( const Poly © ); // Don't use it! + +public: + Poly( const Poly © ) + : 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 PolyPList; +typedef SetIter 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/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/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! --- /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.69]) +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/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/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 -#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 SetIter; -template class RSetIter; - -template -class Set -{ - friend class SetIter; - - T *data; - int _len, used; - T operator[](int cnt) const - { return data[cnt]; } - void operator=(const Set &); // 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 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 void -Set::_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 SetIter -{ - int _cnt; - const Set &_set; - const Set &set() - { return _set; } - -public: - SetIter( const Set &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 INLINE int -SetIter::operator() () -{ - if (cnt() >= (_set.used-1)) - return 0; - _cnt++; - return 1; -} - -template inline T - SetIter::val() const -{ - return _set[_cnt]; -} - - -template -class RSet -{ - friend class RSetIter; - - T *data; - int _len, used; - T &operator[](int cnt) - { return data[cnt]; } - void operator=(const RSet &); // 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 void -RSet::_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 RSetIter -{ - int _cnt; - const RSet &_set; - const RSet &set() - { return _set; } - -public: - RSetIter( const RSet &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 INLINE int - RSetIter::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 +#endif + +#include + +#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 SetIter; +template class RSetIter; + +template +class Set +{ + friend class SetIter; + + T *data; + int _len, used; + T operator[](int cnt) const + { return data[cnt]; } + void operator=(const Set &) // 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 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 void +Set::_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 SetIter +{ + int _cnt; + const Set &_set; + const Set &set() + { return _set; } + +public: + SetIter( const Set &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 INLINE int +SetIter::operator() () +{ + if (cnt() >= (_set.used-1)) + return 0; + _cnt++; + return 1; +} + +template inline T + SetIter::val() const +{ + return _set[_cnt]; +} + + +template +class RSet +{ + friend class RSetIter; + + T *data; + int _len, used; + T &operator[](int cnt) + { return data[cnt]; } + void operator=(const RSet &) // 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 void +RSet::_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 RSetIter +{ + int _cnt; + const RSet &_set; + const RSet &set() + { return _set; } + +public: + RSetIter( const RSet &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 INLINE int + RSetIter::operator() () +{ + if (_cnt >= (_set.used-1)) + return 0; + _cnt++; + return 1; +} + + +#endif /* SET_H */ --- 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/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 - -#include - -#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 © , 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 + +#include + +#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 © , 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/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 - -#include "graphadd.h" -#include - -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)) 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)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 (c1d2) return 0; - if (c2 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 + +#include "graphadd.h" +#include + +#define Dabs(x) (((x)<0) ? (-(x)):(x)) + +#ifndef EPSILON +#define EPSILON 1e-10 +#endif + +#ifdef notdef +#define Pos_cmp(pos1,pos2) (Dabs((pos1)-(pos2)) 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)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 (c1d2) return 0; + if (c2 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/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 -#include - -#include - -#include -#include -#include - -#include -//#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 +#include + +#include + +#include +#include +#include + +#include +//#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/out_file.dist +++ clippoly-0.11/out_file.dist @@ -1,34 +1,34 @@ -a_min_b: -1 -1 -0.5 0 -1.5 0 -PolyMagic -0.25 0.5 -0 1 -0.5 1 -PolyMagic -1.5 1 -2 1 -1.75 0.5 -PolyMagic -b_min_a: -0.5 0 -0 0 -0.25 0.5 -PolyMagic -0.5 1 -1 2 -1.5 1 -PolyMagic -1.75 0.5 -2 0 -1.5 0 -PolyMagic -a_and_b: -0.5 0 -0.25 0.5 -0.5 1 -1.5 1 -1.75 0.5 -1.5 0 -PolyMagic +a_min_b: +1 -1 +0.5 0 +1.5 0 +PolyMagic +0.25 0.5 +0 1 +0.5 1 +PolyMagic +1.5 1 +2 1 +1.75 0.5 +PolyMagic +b_min_a: +0.5 0 +0 0 +0.25 0.5 +PolyMagic +0.5 1 +1 2 +1.5 1 +PolyMagic +1.75 0.5 +2 0 +1.5 0 +PolyMagic +a_and_b: +0.5 0 +0.25 0.5 +0.5 1 +1.5 1 +1.75 0.5 +1.5 0 +PolyMagic --- clippoly-0.11.orig/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 -#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 +#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 + --- /dev/null +++ clippoly-0.11/Makefile.am @@ -0,0 +1,36 @@ +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 = 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 --- /dev/null +++ clippoly-0.11/version.h @@ -0,0 +1 @@ +extern const char clippoly_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 -#include -#ifndef GRAPHMAT_INCLUDE -#include -#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 © ) - { _x = v_x(copy); _y = v_y( copy); return *this; } - const Point &operator=( const Point © ) - { _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 © ); - PointList &operator=( const PointList © ); - -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 +#include +#ifndef GRAPHMAT_INCLUDE +#include +#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 © ) + { _x = v_x(copy); _y = v_y( copy); return *this; } + const Point &operator=( const Point © ) + { _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 © ); + PointList &operator=( const PointList © ); + +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/in_file.test +++ clippoly-0.11/in_file.test @@ -1,13 +1,13 @@ -0.043677 0.0036737 -0.0490363 -0.0524051 -0.00302704 -0.0568021 --0.00233231 -0.000723313 -PolyMagic -0.043677 0.0036737 -0.0213455 0.00153953 -0.0180227 0.00206061 -0.0237406 0.0385219 -0.0850047 0.0289144 -0.0792868 -0.00754689 -0.0442238 -0.00204827 -PolyMagic +0.043677 0.0036737 +0.0490363 -0.0524051 +0.00302704 -0.0568021 +-0.00233231 -0.000723313 +PolyMagic +0.043677 0.0036737 +0.0213455 0.00153953 +0.0180227 0.00206061 +0.0237406 0.0385219 +0.0850047 0.0289144 +0.0792868 -0.00754689 +0.0442238 -0.00204827 +PolyMagic --- clippoly-0.11.orig/in_file.wrong +++ clippoly-0.11/in_file.wrong @@ -1,8 +1,8 @@ -1 -1 -2 1 -0 1 -PolyMagic -0 0 -2 0 -1 2 -PolyMagic +1 -1 +2 1 +0 1 +PolyMagic +0 0 +2 0 +1 2 +PolyMagic --- clippoly-0.11.orig/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 -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846 /* pi */ -#endif - -#include - -#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 +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif + +#include + +#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/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/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 -.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 +.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/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 - -#include -#include -#include - -#include - -#include -#include -#include -#include "nclip.h" - -#ifdef DEBUG1 -#include -#include -#endif -#ifdef DEBUG_NCLIP -#include "poly_io.h" -#include -#include -#include -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 + +#include +#include +#include + +#include + +#include +#include +#include +#include "nclip.h" + +#ifdef DEBUG1 +#include +#include +#endif +#ifdef DEBUG_NCLIP +#include "poly_io.h" +#include +#include +#include +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/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/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/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 - -#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 + +#include "posadder.h" + +void +PosAdder::set(LogicStates boolean) +{ + if (val == TrueFalse) + return; + + switch(boolean) + {case UnKnown: + break; + case TrueFalse: + val = TrueFalse; + break; + case True: + if (val == False) + //error_at_line(0, 0, __FILE__, __LINE__, "Conflict in PosAdder::set (False, True)"); + val = TrueFalse; + else + val = True; + break; + case False: + if (val == True) + //error_at_line(0, 0, __FILE__, __LINE__, "Conflict in PosAdder::set (True, False)"); + val = TrueFalse; + else + val = False; + break; + } +} + + --- clippoly-0.11.orig/posadder.h +++ clippoly-0.11/posadder.h @@ -1,57 +1,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/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 +#include + +#include "poly.h" +#include "poly_io.h" +#include "nclip.h" + +using namespace ::std; + +void +clear(PolyPList &l) +{ + PolyPListIter i(l); + while(i()) + delete i.val(); +} + +int +main(int, char *[]) +{ + Poly *a = read_poly(cin), *b = read_poly(cin); + PolyPList a_min_b, b_min_a, a_and_b; + + // printf("Area a %g b %g\n", a->area(), b->area()); + + clip_poly( *a, *b, a_min_b, b_min_a, a_and_b ); + + cout << "a_min_b:\n" << a_min_b; + cout << "b_min_a:\n" << b_min_a; + cout << "a_and_b:\n" << a_and_b; + + delete a; + delete b; + + clear(a_min_b); + clear(b_min_a); + clear(a_and_b); + + return 0; +} --- /dev/null +++ clippoly-0.11/m4/doorstop @@ -0,0 +1 @@ +hold it open debian/patches/series0000644000000000000000000000001712206225076012032 0ustar debian-changes debian/rules0000775000000000000000000000101712206160434010245 0ustar #!/usr/bin/make -f %: dh $@ --with autoreconf --parallel # Work around quilt patch inability to preserve file modes or # represent deleted files. This is done here because, by coincidence, # it only creates trouble during testing. (a) If test.cc is present, # when "make test" runs it tries to compile test.cc rather than # running the tests. (b) The test scripts must be executable. override_dh_auto_test: chmod --changes +x test0 test1 test2 -rm --verbose --force test.cc err.h patchlevel.h err.3 err.c dh_auto_test