Code

Merge from trunk
authorTed Gould <ted@canonical.com>
Tue, 28 Oct 2008 04:45:31 +0000 (23:45 -0500)
committerTed Gould <ted@canonical.com>
Tue, 28 Oct 2008 04:45:31 +0000 (23:45 -0500)
71 files changed:
po/de.po
src/2geom/basic-intersection.cpp
src/2geom/basic-intersection.h
src/2geom/bezier-curve.h
src/2geom/bezier-to-sbasis.h
src/2geom/bezier-utils.h
src/2geom/bezier.h
src/2geom/choose.h
src/2geom/circle.h
src/2geom/circulator.h
src/2geom/concepts.h
src/2geom/conjugate_gradient.h
src/2geom/convex-cover.h
src/2geom/coord.h
src/2geom/crossing.h
src/2geom/curve.h
src/2geom/curves.h
src/2geom/d2-sbasis.h
src/2geom/d2.h
src/2geom/ellipse.h
src/2geom/elliptical-arc.h
src/2geom/exception.h
src/2geom/forward.h
src/2geom/geom.cpp
src/2geom/geom.h
src/2geom/hvlinesegment.h
src/2geom/interval.h
src/2geom/isnan.h
src/2geom/linear.h
src/2geom/matrix.h
src/2geom/nearest-point.h
src/2geom/ord.h
src/2geom/path-intersection.cpp
src/2geom/path-intersection.h
src/2geom/path.h
src/2geom/pathvector.h
src/2geom/piecewise.h
src/2geom/point.cpp
src/2geom/point.h
src/2geom/poly.h
src/2geom/quadtree.h
src/2geom/rect.h
src/2geom/region.h
src/2geom/sbasis-2d.cpp
src/2geom/sbasis-2d.h
src/2geom/sbasis-curve.h
src/2geom/sbasis-geometric.cpp
src/2geom/sbasis-geometric.h
src/2geom/sbasis-math.cpp
src/2geom/sbasis-math.h
src/2geom/sbasis-poly.cpp
src/2geom/sbasis-poly.h
src/2geom/sbasis-roots.cpp
src/2geom/sbasis-to-bezier.cpp
src/2geom/sbasis-to-bezier.h
src/2geom/sbasis.cpp
src/2geom/sbasis.h
src/2geom/shape.h
src/2geom/solver.h
src/2geom/svg-elliptical-arc.h
src/2geom/svg-path-parser.cpp
src/2geom/svg-path-parser.h
src/2geom/svg-path.h
src/2geom/sweep.h
src/2geom/transforms.h
src/2geom/utils.h
src/livarot/PathCutting.cpp
src/main.cpp
src/preferences.cpp
src/svg/path-string.h
src/svg/svg-path.cpp

index 6ebe9269ebcb9f9e7c002e74a4a24efd55faefd1..17d2fccda405410936c4c79fb6324f14f3331ec0 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -1101,7 +1101,7 @@ msgstr ""
 
 #: ../src/dialogs/export.cpp:631
 msgid "Hide all except selected"
-msgstr "Alle ausser ausgewählte verstecken"
+msgstr "Alle außer ausgewählte verstecken"
 
 #: ../src/dialogs/export.cpp:635
 msgid "In the exported image, hide all objects except those that are selected"
index 334c23feaa50fcaea1010e8d1f3b4ffd699aee16..2a40e7f453973d94c7e932893f58c843144cda55 100644 (file)
@@ -517,6 +517,86 @@ std::vector<std::pair<double, double> > find_intersections( OldBezier a, OldBezi
     std::sort(parameters.begin(), parameters.end());
     return parameters;
 }
+
+
+/**
+ * Compute the Hausdorf distance from A to B only.
+ */
+double hausdorfl(D2<SBasis>& A, D2<SBasis> const& B,
+                 double m_precision,
+                 double *a_t, double* b_t) {
+    std::vector< std::pair<double, double> > xs;
+    std::vector<Point> Az, Bz;
+    sbasis_to_bezier (Az, A);
+    sbasis_to_bezier (Bz, B);
+    find_collinear_normal(xs, Az, Bz, m_precision);
+    double h_dist = 0, h_a_t = 0, h_b_t = 0;
+    double dist = 0;
+    Point Ax = A.at0();
+    double t = Geom::nearest_point(Ax, B);
+    dist = Geom::distance(Ax, B(t));
+    if (dist > h_dist) {
+        h_a_t = 0;
+        h_b_t = t;
+        h_dist = dist;
+    }
+    Ax = A.at1();
+    t = Geom::nearest_point(Ax, B);
+    dist = Geom::distance(Ax, B(t));
+    if (dist > h_dist) {
+        h_a_t = 1;
+        h_b_t = t;
+        h_dist = dist;
+    }
+    for (size_t i = 0; i < xs.size(); ++i)
+    {
+        Point At = A(xs[i].first);
+        Point Bu = B(xs[i].second);
+        double distAtBu = Geom::distance(At, Bu);
+        t = Geom::nearest_point(At, B);
+        dist = Geom::distance(At, B(t));
+        //FIXME: we might miss it due to floating point precision...
+        if (dist >= distAtBu-.1 && distAtBu > h_dist) {
+            h_a_t = xs[i].first;
+            h_b_t = xs[i].second;
+            h_dist = distAtBu;
+        }
+            
+    }
+    if(a_t) *a_t = h_a_t;
+    if(b_t) *b_t = h_b_t;
+    
+    return h_dist;
+}
+
+/** 
+ * Compute the symmetric Hausdorf distance.
+ */
+double hausdorf(D2<SBasis>& A, D2<SBasis> const& B,
+                 double m_precision,
+                 double *a_t, double* b_t) {
+    double h_dist = hausdorfl(A, B, m_precision, a_t, b_t);
+    
+    double dist = 0;
+    Point Bx = B.at0();
+    double t = Geom::nearest_point(Bx, A);
+    dist = Geom::distance(Bx, A(t));
+    if (dist > h_dist) {
+        if(a_t) *a_t = t;
+        if(b_t) *b_t = 0;
+        h_dist = dist;
+    }
+    Bx = B.at1();
+    t = Geom::nearest_point(Bx, A);
+    dist = Geom::distance(Bx, A(t));
+    if (dist > h_dist) {
+        if(a_t) *a_t = t;
+        if(b_t) *b_t = 1;
+        h_dist = dist;
+    }
+    
+    return h_dist;
+}
 };
 
 /*
index a7750e015f15be85e9016f6a335fc6df25e75ee7..77374b5ff934de57ba7955fce1fa2be02eadf22c 100644 (file)
@@ -1,4 +1,39 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
 
+#ifndef SEEN_GEOM_BASICINTERSECTION_H
+#define SEEN_GEOM_BASICINTERSECTION_H
 
 #include <2geom/point.h>
 #include <2geom/sbasis.h>
@@ -58,9 +93,23 @@ void find_collinear_normal (std::vector< std::pair<double, double> >& xs,
                             std::vector<Point> const& B,
                             double precision = 1e-5);
 
+/**
+ * Compute the Hausdorf distance from A to B only.
+ */
+double hausdorfl(D2<SBasis>& A, D2<SBasis> const& B,
+                 double m_precision,
+                 double *a_t=0, double* b_t=0);
 
+/** 
+ * Compute the symmetric Hausdorf distance.
+ */
+double hausdorf(D2<SBasis>& A, D2<SBasis> const& B,
+                double m_precision,
+                double *a_t=0, double* b_t=0);
 }
 
+#endif // !SEEN_GEOM_BASICINTERSECTION_H
+
 /*
   Local Variables:
   mode:c++
index 45d0b61f30b27aeaefc6e38506e866a28bb96dc4..135aa4f71e574785dcd2d3de05411b33b96d600f 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * Bezier-Curve
+/**
+ * \file
+ * \brief Bezier-Curve
  *
  * Authors:
  *             MenTaLguY <mental@rydia.net>
index d5279a5702f0980a0e5cdf44c8fc0b45aa5e4a25..71e39e2c74f40c34c7dbb00ae08afe4fa233fef7 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * bezier-to-sbasis.h
+/**
+ * \file bezier-to-sbasis.h
+ * \brief  \todo brief description
  *
  * Copyright 2006 Nathan Hurst <njh@mail.csse.monash.edu.au>
  *
index 68ae8c0e7fe73fb77a608587b8588d9212831a09..3d79df3b2b50dd6ebf1a847f5f434dea2007b1c3 100644 (file)
@@ -1,7 +1,10 @@
-#ifndef __SP_BEZIER_UTILS_H__
-#define __SP_BEZIER_UTILS_H__
+#ifndef SEEN_GEOM_BEZIER_UTILS_H
+#define SEEN_GEOM_BEZIER_UTILS_H
 
-/*
+/**
+ * \file
+ * \brief  \todo brief description
+ *
  * An Algorithm for Automatically Fitting Digitized Curves
  * by Philip J. Schneider
  * from "Graphics Gems", Academic Press, 1990
@@ -82,7 +85,7 @@ cubic_bezier_poly_coeff(iterator b, Point *pc) {
 }
 
 }
-#endif /* __SP_BEZIER_UTILS_H__ */
+#endif /* !SEEN_GEOM_BEZIER_UTILS_H */
 
 /*
   Local Variables:
index 6e11ad58b3f94dd49b5d9a717eaa7b269d72ef6b..94dd909cafb7b396cb9a4277391c5673001ddbef 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * bezier.h
+/**
+ * \file bezier.h
+ * \brief \todo brief description
  *
  * Copyright 2007  MenTaLguY <mental@rydia.net>
  * Copyright 2007  Michael Sloan <mgsloan@gmail.com>
index 141a23f370faee171e1e952c6a45e08445eed6ba..337569e36e5697a6c027d03fa04fed60319d367b 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * choose.h
+/**
+ * \file choose.h
+ * \brief  \todo brief description
  *
  * Copyright 2006 Nathan Hurst <njh@mail.csse.monash.edu.au>
  *
index 2f81e27bc6ba6aaaaf6e2dfa232636c67e65cc13..1f9871276cfcab45235b2c4d66dc61f9fe40ec4a 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * Circle Curve
+/**
+ * \file
+ * \brief Circle Curve
  *
  * Authors:
  *      Marco Cecchetti <mrcekets at gmail.com>
index 65d337e82b3be1d8ea9565505e8d5285d8f873ed..57f3bf741187231e5374d066d2a25c4e1a4dc4f9 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * ciculator.h
+/**
+ * \file circulator.h
+ * \brief  \todo brief description
  *
  * Copyright 2006 MenTaLguY <mental@rydia.net>
  *
index 6f10c8bb0c31ac6dbdec82f85213dd85b94ff459..8f4d98ef25b7bee62e85e8aa676a82390efbd3b8 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * concepts.h - Declares various mathematical concepts, for restriction of template parameters
+/**
+ * \file
+ * \brief Declares various mathematical concepts, for restriction of template parameters
  *
  * Copyright 2007 Michael Sloan <mgsloan@gmail.com>
  *
index 2d6050fd37e212023e74519675315e614acfffc0..6f4098b5bdeb62c3f0f54e40e56bb0b8378d953f 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * conjugate_gradient.h
+/**
+ * \file
+ * \brief \todo brief description
  *
  * Copyright 2006 Nathan Hurst <njh@mail.csse.monash.edu.au>
  *
index 29f522e91131a21f7511dc7a1253272f7b7f1afb..f221777463b511a028c10c7d321fd4ca9c6fcfdb 100644 (file)
@@ -1,8 +1,9 @@
 #ifndef GEOM_CONVEX_COVER_H
 #define GEOM_CONVEX_COVER_H
 
-/*
- * convex-cover.h
+/**
+ * \file
+ * \brief \todo brief description
  *
  * Copyright 2006 Nathan Hurst <njh@mail.csse.monash.edu.au>
  * Copyright 2006 Michael G. Sloan <mgsloan@gmail.com>
index 99e249e29435c11927f1ad1754fc913c5f9ee9f7..b44a0f71e9705cc2a00d9ae3d24fc5a5ae26d62e 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * coord.h
+/**
+ *  \file
+ *  \brief Defines the Coord "real" type with sufficient precision for coordinates.
  *
  * Copyright 2006 Nathan Hurst <njh@mail.csse.monash.edu.au>
  *
index b16c7e46d1a10a6e2b6d4634520c7433f0bddffb..291f693826358c9728ec0148851a081da21fc65d 100644 (file)
@@ -1,3 +1,37 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
 #ifndef __GEOM_CROSSING_H
 #define __GEOM_CROSSING_H
 
index 6ab05b750ecd5808139ad9aad942252b3b776310..b81548ba832914b756d981fc0bbeb59b215b9a40 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * Abstract Curve Type
+/**
+ * \file
+ * \brief   Abstract Curve Type
  *
  * Authors:
  *             MenTaLguY <mental@rydia.net>
index b0b16df3ddc45d12e91f43f1ee9ff3cedcdf1c9b..f45d1e31fcbcc8e2123560f4ae55f64ac5e894d5 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * this file is only a helper header to include all curve types at once
+/**
+ * \file
+ * \brief   this file is only a helper header to include all curve types at once
  *
  * Authors:
  *             MenTaLguY <mental@rydia.net>
index 91ceb31c98c916eb9f73809f068a67962947507f..dd1a8e11cf875f2b03fa5bba880cbc2693df879d 100644 (file)
@@ -1,3 +1,41 @@
+/**
+ * \file
+ * \brief  Do not include this file \todo brief description
+ *
+ * We don't actually want anyone to
+ * include this, other than D2.h.  If somone else tries, D2
+ * won't be defined.  If it is, this will already be included.
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
 #ifdef _2GEOM_D2  /*This is intentional: we don't actually want anyone to
                     include this, other than D2.h.  If somone else tries, D2
                     won't be defined.  If it is, this will already be included. */
index 731a084a1d495dc9a99cb2041f70c8dcefa0eec8..7e2bbae53ebfb4938872c8a35e8b9706eb1b926e 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * d2.h - Lifts one dimensional objects into 2d 
+/**
+ * \file
+ * \brief   Lifts one dimensional objects into 2d 
  *
  * Copyright 2007 Michael Sloan <mgsloan@gmail.com>
  *
 #include <2geom/concepts.h>
 
 namespace Geom{
-
+/**
+ * The D2 class takes two instances of a scalar data type and treats them
+ * like a point. All operations which make sense on a point are defined for D2.
+ * A D2<double> is a Point. A D2<Interval> is a standard axis aligned rectangle.
+ * D2<SBasis> provides a 2d parametric function which maps t to a point
+ * x(t), y(t)
+ */
 template <class T>
 class D2{
     //BOOST_CLASS_REQUIRE(T, boost, AssignableConcept);
@@ -247,6 +254,19 @@ D2<T> operator*(D2<T> const &v, Matrix const &m) {
     return ret;
 }
 
+//IMPL: MultiplicableConcept
+template <typename T>
+inline D2<T>
+operator*(D2<T> const & a, T const & b) {
+    boost::function_requires<MultiplicableConcept<T> >();
+    D2<T> ret;
+    for(unsigned i = 0; i < 2; i++)
+        ret[i] = a[i] * b;
+    return ret;
+}
+
+//IMPL: 
+
 //IMPL: OffsetableConcept
 template <typename T>
 inline D2<T>
index 1f0dfce632792c8e5854fd095e95773a3a0aa118..d5b882bc4e952fb4e9823386505ad69dbc4c43f9 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * Ellipse Curve
+/**
+ * \file
+ * \brief  Ellipse Curve
  *
  * Authors:
  *      Marco Cecchetti <mrcekets at gmail.com>
index 46b94c0df453dd13a07fe27835a4fface428a8c0..24b4fcf4636d2fbbab6ee14fea11492503ef3c4c 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * Elliptical Arc - implementation of the svg elliptical arc path element
+/**
+ * \file
+ * \brief  Elliptical Arc - implementation of the svg elliptical arc path element
  *
  * Authors:
  *             MenTaLguY <mental@rydia.net>
index 6151f7a57355be8b7b942c6e25e89e29d71c1ccf..99db54b457d9180945cad3663cefbda547e52f5e 100644 (file)
@@ -1,7 +1,9 @@
 #ifndef LIB2GEOM_EXCEPTION_HEADER
 #define LIB2GEOM_EXCEPTION_HEADER
 
-/** Defines the different types of exceptions that 2geom can throw.
+/**
+ * \file
+ * \brief  Defines the different types of exceptions that 2geom can throw.
  *
  * Copyright 2007 Johan Engelen <goejendaagh@zonnet.nl>
  *
index d4ac1af1ed514326add0c13e4234dcfad0658067..184801ef42c4ccbda56bcf947e53427f27557aec 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * forward - this file contains forward declarations of 2geom types
+/**
+ * \file
+ * \brief  Contains forward declarations of 2geom types
  *
  * Authors:
  *  Johan Engelen <goejendaagh@zonnet.nl>
index ded1a19402a74d143c5376d37a86d2d32b000d81..d0689981a78ac2388a753d65588b4d146f60dd63 100644 (file)
@@ -1,5 +1,6 @@
-/** @file
- * @brief Various geometrical calculations.
+/**
+ *  \file geom.cpp
+ *  \brief Various geometrical calculations.
  */
 
 #ifdef HAVE_CONFIG_H
index 210d236a1a9c91fdcd61c52a94bb392c7651fc13..aeb40f7e1b14a662a84bb2555e02c383c0134612 100644 (file)
@@ -1,7 +1,8 @@
-/** @file
- * @brief Various geometrical calculations
- */
-/* Authors:
+/**
+ *  \file
+ *  \brief Various geometrical calculations
+ *
+ *  Authors:
  *   Nathan Hurst <njh@mail.csse.monash.edu.au>
  *
  * Copyright (C) 1999-2002 authors
index 66de31d70364b8ef4f0071d51db8bd7385e20042..3e12876824e7e1e51c5df1e90426858d03e843a9 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * Horizontal and Vertical Line Segment
+/**
+ * \file
+ * \brief  Horizontal and Vertical Line Segment
  *
  * Copyright 2008  Marco Cecchetti <mrcekets at gmail.com>
  *
index 2d9f4abd85ce01582edce7d679f7a34bf862ab31..8f7a0b2a167bf9e40cb9b81635757a657941d920 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * interval.h - Simple closed interval class
+/**
+ * \file
+ * \brief  Simple closed interval class
  *
  * Copyright 2007 Michael Sloan <mgsloan@gmail.com>
  *
index 6b94daa6e5c61826784c2799af54ee1226a37df5..b4e7341ff8032791a10254944f16c3bbbc0ca99d 100644 (file)
@@ -1,3 +1,37 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
 #ifndef _2GEOM_ISNAN_H__
 #define _2GEOM_ISNAN_H__
 
index bc7af564c9ad5dacf1037378bb3f88619f11150a..4594e17bed6250cd4fda53551d0c9ffdcceaafd7 100644 (file)
@@ -1,5 +1,6 @@
-/*
- *  linear.h - Linear fragment function class
+/**
+ * \file
+ * \brief  Linear fragment function class
  *
  *  Authors:
  *   Nathan Hurst <njh@mail.csse.monash.edu.au>
index c81efab68a452576dffab8b7eb1fc8582ff09f84..e207bf812e2d7562350a32ff3417ea6a01b867e5 100644 (file)
@@ -2,7 +2,7 @@
 #define __Geom_MATRIX_H__
 
 /** \file
- * Definition of Geom::Matrix types.
+ *  \brief Definition of Geom::Matrix types.
  *
  * Main authors:
  *   Lauris Kaplinski <lauris@kaplinski.com>:
index 0ca28c4f218fcfdb8d024cac2da94e23d182b43a..19485242cbe5c2a36c45b25f24e0fc607ed0917c 100644 (file)
@@ -1,6 +1,6 @@
-/*
- * nearest point routines for D2<SBasis> and Piecewise<D2<SBasis>>
- *
+/**
+ * \file
+ * \brief  nearest point routines for D2<SBasis> and Piecewise<D2<SBasis>>
  *
  * Authors:
  *
index ec5bc650c8cdd3c855e58bf584333af4f753aa09..8c011529a7576ea0dc619bf2df7c7e340f20c4f4 100644 (file)
@@ -1,3 +1,36 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
 
 #ifndef __2GEOM_ORD__
 #define __2GEOM_ORD__
index 2612aa12507a4a8ce21fd3384398ce6bbb76dabc..715c67c23264fe2b8091f40f6db8d6599c9e0be0 100644 (file)
@@ -9,7 +9,8 @@
 
 namespace Geom {
 
-/* This function computes the winding of the path, given a reference point.
+/**
+ * This function computes the winding of the path, given a reference point.
  * Positive values correspond to counter-clockwise in the mathematical coordinate system,
  * and clockwise in screen coordinates.  This particular implementation casts a ray in
  * the positive x direction.  It iterates the path, checking for intersection with the
@@ -102,7 +103,8 @@ int winding(Path const &path, Point p) {
   return wind;
 }
 
-/* This function should only be applied to simple paths (regions), as otherwise
+/**
+ * This function should only be applied to simple paths (regions), as otherwise
  * a boolean winding direction is undefined.  It returns true for fill, false for
  * hole.  Defaults to using the sign of area when it reaches funny cases.
  */
@@ -143,13 +145,14 @@ bool path_direction(Path const &p) {
 
 //pair intersect code based on njh's pair-intersect
 
-// A little sugar for appending a list to another
+/** A little sugar for appending a list to another */
 template<typename T>
 void append(T &a, T const &b) {
     a.insert(a.end(), b.begin(), b.end());
 }
 
-/* Finds the intersection between the lines defined by A0 & A1, and B0 & B1.
+/**
+ * Finds the intersection between the lines defined by A0 & A1, and B0 & B1.
  * Returns through the last 3 parameters, returning the t-values on the lines
  * and the cross-product of the deltas (a useful byproduct).  The return value
  * indicates if the time values are within their proper range on the line segments.
@@ -255,7 +258,8 @@ intersect_polish_root (Curve const &A, double &s,
     gsl_vector_free (x);
 }
 
-/* This uses the local bounds functions of curves to generically intersect two.
+/**
+ * This uses the local bounds functions of curves to generically intersect two.
  * It passes in the curves, time intervals, and keeps track of depth, while
  * returning the results through the Crossings parameter.
  */
@@ -298,14 +302,16 @@ void pair_intersect(Curve const & A, double Al, double Ah,
                     A, Al, Ah,
                     ret, depth+1);
 }
-// A simple wrapper around pair_intersect
+
+/** A simple wrapper around pair_intersect */
 Crossings SimpleCrosser::crossings(Curve const &a, Curve const &b) {
     Crossings ret;
     pair_intersect(a, 0, 1, b, 0, 1, ret);
     return ret;
 }
 
-/* Takes two paths and time ranges on them, with the invariant that the
+/**
+ * Takes two paths and time ranges on them, with the invariant that the
  * paths are monotonic on the range.  Splits A when the linear intersection
  * doesn't exist or is inaccurate.  Uses the fact that it is monotonic to
  * do very fast local bounds.
@@ -346,7 +352,7 @@ void mono_pair(Path const &A, double Al, double Ah,
               ret, depth+1);
 }
 
-// This returns the times when the x or y derivative is 0 in the curve.
+/** This returns the times when the x or y derivative is 0 in the curve. */
 std::vector<double> curve_mono_splits(Curve const &d) {
     std::vector<double> rs = d.roots(0, X);
     append(rs, d.roots(0, Y));
@@ -354,7 +360,7 @@ std::vector<double> curve_mono_splits(Curve const &d) {
     return rs;
 }
 
-// Convenience function to add a value to each entry in a vector of doubles.
+/** Convenience function to add a value to each entry in a vector of doubles. */
 std::vector<double> offset_doubles(std::vector<double> const &x, double offs) {
     std::vector<double> ret;
     for(unsigned i = 0; i < x.size(); i++) {
@@ -363,7 +369,8 @@ std::vector<double> offset_doubles(std::vector<double> const &x, double offs) {
     return ret;
 }
 
-/* Finds all the monotonic splits for a path.  Only includes the split between
+/**
+ * Finds all the monotonic splits for a path.  Only includes the split between
  * curves if they switch derivative directions at that point.
  */
 std::vector<double> path_mono_splits(Path const &p) {
@@ -394,7 +401,8 @@ std::vector<double> path_mono_splits(Path const &p) {
     return ret;
 }
 
-/* Applies path_mono_splits to multiple paths, and returns the results such that 
+/**
+ * Applies path_mono_splits to multiple paths, and returns the results such that 
  * time-set i corresponds to Path i.
  */
 std::vector<std::vector<double> > paths_mono_splits(std::vector<Path> const &ps) {
@@ -404,7 +412,8 @@ std::vector<std::vector<double> > paths_mono_splits(std::vector<Path> const &ps)
     return ret;
 }
 
-/* Processes the bounds for a list of paths and a list of splits on them, yielding a list of rects for each.
+/**
+ * Processes the bounds for a list of paths and a list of splits on them, yielding a list of rects for each.
  * Each entry i corresponds to path i of the input.  The number of rects in each entry is guaranteed to be the
  * number of splits for that path, subtracted by one.
  */
@@ -419,7 +428,8 @@ std::vector<std::vector<Rect> > split_bounds(std::vector<Path> const &p, std::ve
     return ret;
 }
 
-/* This is the main routine of "MonoCrosser", and implements a monotonic strategy on multiple curves.
+/**
+ * This is the main routine of "MonoCrosser", and implements a monotonic strategy on multiple curves.
  * Finds crossings between two sets of paths, yielding a CrossingSet.  [0, a.size()) of the return correspond
  * to the sorted crossings of a with paths of b.  The rest of the return, [a.size(), a.size() + b.size()],
  * corresponds to the sorted crossings of b with paths of a.
index 73dc3da8bbd48b1c2c2614f8936409f055da4bfc..4eef168237a59c00a6ce04726aa41c56de164e9e 100644 (file)
@@ -1,3 +1,37 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
 #ifndef __GEOM_PATH_INTERSECTION_H
 #define __GEOM_PATH_INTERSECTION_H
 
index 1b59ea011d4a566a31662ca0c128ac6826ea8f8d..e02b749e789093f7811796f415209c71f6cba731 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * Path - Series of continuous curves
+/**
+ * \file
+ * \brief  Path - Series of continuous curves
  *
  * Authors:
  *             MenTaLguY <mental@rydia.net>
@@ -564,6 +565,11 @@ public:
     }
   }
 
+
+  /*
+   * It is important to note that the coordinates passed to appendNew should be finite!
+   */
+
   template <typename CurveType, typename A>
   void appendNew(A a) {
     unshare();
index cdc774c557bb39540b93c8d8d2f6254c7ec6aa62..5df3ad00c2da9fa47e6534dc9810dd94c856b475 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * PathVector - std::vector containing Geom::Path
+/**
+ * \file
+ * \brief PathVector - std::vector containing Geom::Path
  * This file provides a set of operations that can be performed on PathVector,
  * e.g. an affine transform.
  *
index d25c04bc4cf968f1ab272eb7e46f32998726cf82..ec3ba26ce9094337972561418d69002ef989b3d7 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * piecewise.h - Piecewise function class
+/**
+ * \file
+ * \brief Piecewise function class
  *
  * Copyright 2007 Michael Sloan <mgsloan@gmail.com>
  *
 #include <boost/concept_check.hpp>
 
 namespace Geom {
-
+/**
+ * %Piecewise function class.
+ * The Piecewise class manages a sequence of elements of a type as segments and
+ * the ’cuts’ between them. These cuts are time values which separate the pieces.
+ * This function representation allows for more interesting functions, as it provides
+ * a viable output for operations such as inversion, which may require multiple
+ * SBasis to properly invert the original.
+ * As for technical details, while the actual SBasis segments begin on the first
+ * cut and end on the last, the function is defined throughout all inputs by ex-
+ * tending the first and last segments. The exact switching between segments is
+ * arbitrarily such that beginnings (t=0) have preference over endings (t=1). This
+ * only matters if it is discontinuous at the location.
+ * \f[
+ *      f(t) \rightarrow \left\{ 
+ *      \begin{array}{cc}
+ *      s_1,& t <= c_2 \\
+ *      s_2,& c_2 <= t <= c_3\\
+ *      \ldots
+ *      s_n,& c_n <= t
+ *      \end{array}\right.
+ * \f]
+ */
 template <typename T>
 class Piecewise {
   BOOST_CLASS_REQUIRE(T, Geom, FragmentConcept);
index 42a7ecef305bf100fb168fb803a3726c82488882..5dd7b52f295126b468f76d49e239202d561566cb 100644 (file)
@@ -6,7 +6,7 @@
 
 namespace Geom {
 
-/** Scales this vector to make it a unit vector (within rounding error).
+/** \brief Scales this vector to make it a unit vector (within rounding error).
  *
  *  The current version tries to handle infinite coordinates gracefully,
  *  but it's not clear that any callers need that.
@@ -38,23 +38,23 @@ void Point::normalize() {
             }
         }
         switch (n_inf_coords) {
-        case 0: {
-            /* Can happen if both coords are near +/-DBL_MAX. */
-            *this /= 4.0;
-            len = hypot(_pt[0], _pt[1]);
-            assert(len != inf);
-            *this /= len;
-            break;
-        }
-        case 1: {
-            *this = tmp;
-            break;
-        }
-        case 2: {
-            *this = tmp * sqrt(0.5);
-            break;
+            case 0: {
+                /* Can happen if both coords are near +/-DBL_MAX. */
+                *this /= 4.0;
+                len = hypot(_pt[0], _pt[1]);
+                assert(len != inf);
+                *this /= len;
+                break;
+            }
+            case 1: {
+                *this = tmp;
+                break;
+            }
+            case 2: {
+                *this = tmp * sqrt(0.5);
+                break;
+            }
         }
-       }
     }
 }
 
index 2cab3d7fe056356f095177cb6495bcda286b2d4f..e6e74242d5d7c4adae2982307fb1859ef15b2da3 100644 (file)
@@ -1,8 +1,9 @@
 #ifndef SEEN_Geom_POINT_H
 #define SEEN_Geom_POINT_H
 
-/** \file
- * Cartesian point class.
+/**
+ *  \file
+ *  \brief Defines a Cartesian 2D Point class.
  */
 
 #include <iostream>
@@ -16,7 +17,7 @@ enum Dim2 { X=0, Y=1 };
 
 class Matrix;
 
-/// Cartesian point.
+/// Cartesian 2D point.
 class Point {
     Coord _pt[2];
 
index 152626698c574b0847475348c463509e422400dc..86041a8897ec5f54a977e1c426b0d75572782e78 100644 (file)
@@ -1,3 +1,37 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
 #ifndef LIB2GEOM_SEEN_POLY_H
 #define LIB2GEOM_SEEN_POLY_H
 #include <assert.h>
index 0770cd5f864bdfa1fe45e747de7357cb5fcbce33..5338698cff0efc6e8eb0071f602685d3107227c2 100644 (file)
@@ -1,3 +1,37 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
 #include <vector>
 #include <cassert>
 
index ee1b0d76497507c8368bf7556d0ae1514628bb3a..563c8a05869713e5f3c62af4619876736f39f304 100644 (file)
@@ -1,6 +1,8 @@
+/**
+ * \file
+ * \brief  D2<Interval> specialization to Rect
+ */
 /*
- * rect.h - D2<Interval> specialization to Rect
- *
  * Copyright 2007 Michael Sloan <mgsloan@gmail.com>
  *
  * This library is free software; you can redistribute it and/or
 #include <boost/optional/optional.hpp>
 
 namespace Geom {
-
+/** D2<Interval> specialization to Rect */
 typedef D2<Interval> Rect;
 
 Rect unify(const Rect &, const Rect &);
-
+/**
+ * %Rect class.
+ * The Rect class is actually a specialisation of D2<Interval>.
+ * 
+ */
 template<>
 class D2<Interval> {
   private:
@@ -74,7 +80,7 @@ class D2<Interval> {
     inline Point min() const { return Point(f[X].min(), f[Y].min()); }
     inline Point max() const { return Point(f[X].max(), f[Y].max()); }
 
-    /** returns the four corners of the rectangle in positive order
+    /** Returns the four corners of the rectangle in positive order
      *  (clockwise if +Y is up, anticlockwise if +Y is down) */
     Point corner(unsigned i) const {
         switch(i % 4) {
@@ -94,40 +100,43 @@ class D2<Interval> {
     inline double width() const { return f[X].extent(); }
     inline double height() const { return f[Y].extent(); }
 
-    /** returns a vector from min to max. */
+    /** Returns a vector from min to max. */
     inline Point dimensions() const { return Point(f[X].extent(), f[Y].extent()); }
     inline Point midpoint() const { return Point(f[X].middle(), f[Y].middle()); }
 
+/**
+ * Compute the area of this rectangle.  Note that a zero area rectangle is not necessarily empty - just as the interval [0,0] contains one point, the rectangle [0,0] x [0,0] contains 1 point and no area.
+ */
     inline double area() const { return f[X].extent() * f[Y].extent(); }
     inline double maxExtent() const { return std::max(f[X].extent(), f[Y].extent()); }
 
     inline bool isEmpty()                 const { 
-       return f[X].isEmpty()        || f[Y].isEmpty(); 
+        return f[X].isEmpty()        || f[Y].isEmpty(); 
     }
     inline bool intersects(Rect const &r) const { 
-       return f[X].intersects(r[X]) && f[Y].intersects(r[Y]); 
+        return f[X].intersects(r[X]) && f[Y].intersects(r[Y]); 
     }
     inline bool contains(Rect const &r)   const { 
-       return f[X].contains(r[X]) && f[Y].contains(r[Y]); 
+        return f[X].contains(r[X]) && f[Y].contains(r[Y]); 
     }
     inline bool contains(Point const &p)  const {
-       return f[X].contains(p[X]) && f[Y].contains(p[Y]);
+        return f[X].contains(p[X]) && f[Y].contains(p[Y]);
     }
 
     inline void expandTo(Point p)        { 
-       f[X].extendTo(p[X]);  f[Y].extendTo(p[Y]); 
+        f[X].extendTo(p[X]);  f[Y].extendTo(p[Y]); 
     }
     inline void unionWith(Rect const &b) { 
-       f[X].unionWith(b[X]); f[Y].unionWith(b[Y]); 
+        f[X].unionWith(b[X]); f[Y].unionWith(b[Y]); 
     }
 
     inline void expandBy(double amnt)    { 
-       f[X].expandBy(amnt);  f[Y].expandBy(amnt); 
+        f[X].expandBy(amnt);  f[Y].expandBy(amnt); 
     }
     inline void expandBy(Point const p)  { 
-       f[X].expandBy(p[X]);  f[Y].expandBy(p[Y]); 
+        f[X].expandBy(p[X]);  f[Y].expandBy(p[Y]); 
     }
-
+    
     /** Transforms the rect by m. Note that it gives correct results only for scales and translates,
         in the case of rotations, the area of the rect will grow as it cannot rotate. */
     inline Rect operator*(Matrix const m) const { 
@@ -140,8 +149,10 @@ inline Rect unify(Rect const & a, Rect const & b) {
     return Rect(unify(a[X], b[X]), unify(a[Y], b[Y]));
 }
 
-/** Returns the smallest rectangle that encloses both rectangles.
-  * An empty argument is assumed to be an empty rectangle */
+/** 
+ * Returns the smallest rectangle that encloses both rectangles.
+ * An empty argument is assumed to be an empty rectangle
+ */
 inline boost::optional<Rect> unify(boost::optional<Rect> const & a, boost::optional<Rect> const & b) {
     if (!a) {
         return b;
@@ -169,30 +180,33 @@ inline boost::optional<Rect> intersect(Rect const & a, Rect const & b) {
 inline
 double distanceSq( Point const& p, Rect const& rect )
 {
-       double dx = 0, dy = 0;
-       if ( p[X] < rect.left() )
-       {
-               dx = p[X] - rect.left();
-       }
-       else if ( p[X] > rect.right() )
-       {
-               dx = rect.right() - p[X];
-       }
-       if ( p[Y] < rect.top() )
-       {
-               dy = rect.top() - p[Y];
-       }
-       else if (  p[Y] > rect.bottom() )
-       {
-               dy = p[Y] - rect.bottom();
-       }
-       return dx*dx + dy*dy;
+    double dx = 0, dy = 0;
+    if ( p[X] < rect.left() )
+    {
+        dx = p[X] - rect.left();
+    }
+    else if ( p[X] > rect.right() )
+    {
+        dx = rect.right() - p[X];
+    }
+    if ( p[Y] < rect.top() )
+    {
+        dy = rect.top() - p[Y];
+    }
+    else if (  p[Y] > rect.bottom() )
+    {
+        dy = p[Y] - rect.bottom();
+    }
+    return dx*dx + dy*dy;
 }
 
+/**
+ * Returns the smallest distance between p and rect.
+ */
 inline 
 double distance( Point const& p, Rect const& rect )
 {
-       return std::sqrt(distanceSq(p, rect));
+    return std::sqrt(distanceSq(p, rect));
 }
 
 
index 960a570a4c6622aaa56c1dd21a0730a5b30fd95c..7b2f5763da69e072d78d15803c7470ace4ce68f1 100644 (file)
@@ -1,3 +1,37 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
 #ifndef __2GEOM_REGION_H
 #define __2GEOM_REGION_H
 
index 79e99519af330e12a308764120f42d575ec02f53..9566e0a198fb5f5b153821ff73b60441c581f1c8 100644 (file)
@@ -1,4 +1,5 @@
 #include <2geom/sbasis-2d.h>
+#include <2geom/sbasis-geometric.h>
 
 namespace Geom{
 
@@ -69,6 +70,122 @@ compose_each(D2<SBasis2d> const &fg, D2<SBasis> const &p) {
     return D2<SBasis>(compose(fg[X], p), compose(fg[Y], p));
 }
 
+SBasis2d partial_derivative(SBasis2d const &f, int dim) {
+    SBasis2d result;
+    for(unsigned i = 0; i < f.size(); i++) {
+        result.push_back(Linear2d(0,0,0,0));
+    }
+    result.us = f.us;
+    result.vs = f.vs;
+
+    for(unsigned i = 0; i < f.us; i++) {
+        for(unsigned j = 0; j < f.vs; j++) {
+            Linear2d lin = f.index(i,j);
+            Linear2d dlin(lin[1+dim]-lin[0], lin[1+2*dim]-lin[dim], lin[3-dim]-lin[2*(1-dim)], lin[3]-lin[2-dim]);
+            result[i+j*result.us] += dlin;
+            unsigned di = dim?j:i;
+            if (di>=1){
+                float motpi = dim?-1:1;
+                Linear2d ds_lin_low( lin[0], -motpi*lin[1], motpi*lin[2], -lin[3] );
+                result[(i+dim-1)+(j-dim)*result.us] += di*ds_lin_low;
+                
+                Linear2d ds_lin_hi( lin[1+dim]-lin[0], lin[1+2*dim]-lin[dim], lin[3]-lin[2-dim], lin[3-dim]-lin[2-dim] );
+                result[i+j*result.us] += di*ds_lin_hi;                
+            }
+        }
+    }
+    return result;
+}
+
+/**
+ * Finds a path which traces the 0 contour of f, traversing from A to B as a single d2<sbasis>.
+ * degmax specifies the degree (degree = 2*degmax-1, so a degmax of 2 generates a cubic fit).
+ * The algorithm is based on dividing out derivatives at each end point and does not use the curvature for fitting.
+ * It is less accurate than sb2d_cubic_solve, although this may be fixed in the future. 
+ */
+D2<SBasis>
+sb2dsolve(SBasis2d const &f, Geom::Point const &A, Geom::Point const &B, unsigned degmax){
+    D2<SBasis>result(Linear(A[X],B[X]),Linear(A[Y],B[Y]));
+    //g_warning("check f(A)= %f = f(B) = %f =0!", f.apply(A[X],A[Y]), f.apply(B[X],B[Y]));
+
+    SBasis2d dfdu = partial_derivative(f, 0);
+    SBasis2d dfdv = partial_derivative(f, 1);
+    Geom::Point dfA(dfdu.apply(A[X],A[Y]),dfdv.apply(A[X],A[Y]));
+    Geom::Point dfB(dfdu.apply(B[X],B[Y]),dfdv.apply(B[X],B[Y]));
+    Geom::Point nA = dfA/(dfA[X]*dfA[X]+dfA[Y]*dfA[Y]);
+    Geom::Point nB = dfB/(dfB[X]*dfB[X]+dfB[Y]*dfB[Y]);
+
+    double fact_k=1;
+    double sign = 1.;
+    for(unsigned k=1; k<degmax; k++){
+        // these two lines make the solutions worse!
+        //fact_k *= k;
+        //sign = -sign;
+        SBasis f_on_curve = compose(f,result);
+        Linear reste = f_on_curve[k];
+        double ax = -reste[0]/fact_k*nA[X];
+        double ay = -reste[0]/fact_k*nA[Y];
+        double bx = -sign*reste[1]/fact_k*nB[X];
+        double by = -sign*reste[1]/fact_k*nB[Y];
+
+        result[X].push_back(Linear(ax,bx));
+        result[Y].push_back(Linear(ay,by));
+        //sign *= 3;
+    }    
+    return result;
+}
+
+/**
+ * Finds a path which traces the 0 contour of f, traversing from A to B as a single cubic d2<sbasis>.
+ * The algorithm is based on matching direction and curvature at each end point.
+ */
+//TODO: handle the case when B is "behind" A for the natural orientation of the level set.
+//TODO: more generally, there might be up to 4 solutions. Choose the best one!
+D2<SBasis>
+sb2d_cubic_solve(SBasis2d const &f, Geom::Point const &A, Geom::Point const &B){
+    D2<SBasis>result;//(Linear(A[X],B[X]),Linear(A[Y],B[Y]));
+    //g_warning("check 0 = %f = %f!", f.apply(A[X],A[Y]), f.apply(B[X],B[Y]));
+
+    SBasis2d f_u  = partial_derivative(f  , 0);
+    SBasis2d f_v  = partial_derivative(f  , 1);
+    SBasis2d f_uu = partial_derivative(f_u, 0);
+    SBasis2d f_uv = partial_derivative(f_v, 0);
+    SBasis2d f_vv = partial_derivative(f_v, 1);
+
+    Geom::Point dfA(f_u.apply(A[X],A[Y]),f_v.apply(A[X],A[Y]));
+    Geom::Point dfB(f_u.apply(B[X],B[Y]),f_v.apply(B[X],B[Y]));
+
+    Geom::Point V0 = rot90(dfA);
+    Geom::Point V1 = rot90(dfB);
+    
+    double D2fVV0 = f_uu.apply(A[X],A[Y])*V0[X]*V0[X]+
+                  2*f_uv.apply(A[X],A[Y])*V0[X]*V0[Y]+
+                    f_vv.apply(A[X],A[Y])*V0[Y]*V0[Y];
+    double D2fVV1 = f_uu.apply(B[X],B[Y])*V1[X]*V1[X]+
+                  2*f_uv.apply(B[X],B[Y])*V1[X]*V1[Y]+
+                    f_vv.apply(B[X],B[Y])*V1[Y]*V1[Y];
+
+    std::vector<D2<SBasis> > candidates = cubics_fitting_curvature(A,B,V0,V1,D2fVV0,D2fVV1);
+    if (candidates.size()==0) {
+        return D2<SBasis>(Linear(A[X],B[X]),Linear(A[Y],B[Y]));
+    }
+    //TODO: I'm sure std algorithm could do that for me...
+    double error = -1;
+    unsigned best = 0;
+    for (unsigned i=0; i<candidates.size(); i++){
+        Interval bounds = bounds_fast(compose(f,candidates[i]));
+        double new_error = (fabs(bounds.max())>fabs(bounds.min()) ? fabs(bounds.max()) : fabs(bounds.min()) );
+        if ( new_error < error || error < 0 ){
+            error = new_error;
+            best = i;
+        }
+    }
+    return candidates[best];
+}
+
+
+
+
 };
 
 /*
index 1845b5c99305b6bc5923651f13639f41d3f56c29..c29d53bcb56250cdd596a2fbb884e6aaf0b2afc8 100644 (file)
@@ -1,3 +1,38 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      Nathan Hurst <?@?.?>
+ *      JFBarraud <?@?.?>
+ * 
+ * Copyright 2006-2008  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
 #ifndef SEEN_SBASIS_2D_H
 #define SEEN_SBASIS_2D_H
 #include <vector>
@@ -16,7 +51,12 @@ public:
         v 0,2
     */
     double a[4];
-    Linear2d() {}
+    Linear2d() {
+        a[0] = 0; 
+        a[1] = 0;
+        a[2] = 0; 
+        a[3] = 0; 
+    }
     Linear2d(double aa) {
         for(unsigned i = 0 ; i < 4; i ++) 
             a[i] = aa;
@@ -273,7 +313,7 @@ SBasis2d multiply(SBasis2d const &a, SBasis2d const &b);
 
 SBasis2d integral(SBasis2d const &c);
 
-SBasis2d derivative(SBasis2d const &a);
+SBasis2d partial_derivative(SBasis2d const &a, int dim);
 
 SBasis2d sqrt(SBasis2d const &a, int k);
 
@@ -310,6 +350,12 @@ inline std::ostream &operator<< (std::ostream &out_file, const SBasis2d & p) {
     return out_file;
 }
 
+D2<SBasis>
+sb2dsolve(SBasis2d const &f, Geom::Point const &A, Geom::Point const &B, unsigned degmax=2);
+
+D2<SBasis>
+sb2d_cubic_solve(SBasis2d const &f, Geom::Point const &A, Geom::Point const &B);
+
 };
 
 /*
index 6b3888594a19c691e93461ec466d446535ac4250..e11919401453a7ec804f277a404acce6a9018ceb 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * Simmetric Power Bais Curve
+/**
+ * \file
+ * \brief Symmetric Power Basis Curve
  *
  * Authors:
  *             MenTaLguY <mental@rydia.net>
index 887ca9995f5184349ac5b09dd3c9c93ed6de4928..f0170ec6bbbcdf17139118ab7f64d930d6156a69 100644 (file)
@@ -127,6 +127,12 @@ Geom::cutAtRoots(Piecewise<D2<SBasis> > const &M, double ZERO){
     return partition(M,rts);
 }
 
+/** Return a function which gives the angle of vect at each point.
+ \param vect a piecewise parameteric curve.
+ \param tol the maximum error allowed.
+ \param order the maximum degree to use for approximation
+
+*/
 Piecewise<SBasis>
 Geom::atan2(Piecewise<D2<SBasis> > const &vect, double tol, unsigned order){
     Piecewise<SBasis> result;
@@ -152,24 +158,47 @@ Geom::atan2(Piecewise<D2<SBasis> > const &vect, double tol, unsigned order){
     }
     return result;
 }
+/** Return a function which gives the angle of vect at each point.
+ \param vect a piecewise parameteric curve.
+ \param tol the maximum error allowed.
+ \param order the maximum degree to use for approximation
+
+*/
 Piecewise<SBasis>
 Geom::atan2(D2<SBasis> const &vect, double tol, unsigned order){
     return atan2(Piecewise<D2<SBasis> >(vect),tol,order);
 }
 
-//tan2 is the pseudo-inverse of atan2.  It takes an angle and returns a unit_vector that points in the direction of angle.
+/** tan2 is the pseudo-inverse of atan2.  It takes an angle and returns a unit_vector that points in the direction of angle.
+ \param angle a piecewise function of angle wrt t.
+ \param tol the maximum error allowed.
+ \param order the maximum degree to use for approximation
+
+*/
 D2<Piecewise<SBasis> >
 Geom::tan2(SBasis const &angle, double tol, unsigned order){
     return tan2(Piecewise<SBasis>(angle), tol, order);
 }
 
+/** tan2 is the pseudo-inverse of atan2.  It takes an angle and returns a unit_vector that points in the direction of angle.
+ \param angle a piecewise function of angle wrt t.
+ \param tol the maximum error allowed.
+ \param order the maximum degree to use for approximation
+
+*/
 D2<Piecewise<SBasis> >
 Geom::tan2(Piecewise<SBasis> const &angle, double tol, unsigned order){
     return D2<Piecewise<SBasis> >(cos(angle, tol, order), sin(angle, tol, order));
 }
 
-//unitVector(x,y) is computed as (b,-a) where a and b are solutions of:
-//     ax+by=0 (eqn1)   and   a^2+b^2=1 (eqn2)
+/** Return a Piecewise<D2<SBasis> > which points in the same direction as V_in, but has unit_length.
+ \param V_in the original path.
+ \param tol the maximum error allowed.
+ \param order the maximum degree to use for approximation
+
+unitVector(x,y) is computed as (b,-a) where a and b are solutions of:
+     ax+by=0 (eqn1)   and   a^2+b^2=1 (eqn2)
+*/
 Piecewise<D2<SBasis> >
 Geom::unitVector(D2<SBasis> const &V_in, double tol, unsigned order){
     D2<SBasis> V = RescaleForNonVanishingEnds(V_in);
@@ -234,6 +263,14 @@ Geom::unitVector(D2<SBasis> const &V_in, double tol, unsigned order){
     }
 }
 
+/** Return a Piecewise<D2<SBasis> > which points in the same direction as V_in, but has unit_length.
+ \param V_in the original path.
+ \param tol the maximum error allowed.
+ \param order the maximum degree to use for approximation
+
+unitVector(x,y) is computed as (b,-a) where a and b are solutions of:
+     ax+by=0 (eqn1)   and   a^2+b^2=1 (eqn2)
+*/
 Piecewise<D2<SBasis> >
 Geom::unitVector(Piecewise<D2<SBasis> > const &V, double tol, unsigned order){
     Piecewise<D2<SBasis> > result;
@@ -248,6 +285,11 @@ Geom::unitVector(Piecewise<D2<SBasis> > const &V, double tol, unsigned order){
     return result;
 }
 
+/** returns a function giving the arclength at each point in M.
+ \param M the Element.
+ \param tol the maximum error allowed.
+
+*/
 Piecewise<SBasis> 
 Geom::arcLengthSb(Piecewise<D2<SBasis> > const &M, double tol){
     Piecewise<D2<SBasis> > dM = derivative(M);
@@ -256,11 +298,18 @@ Geom::arcLengthSb(Piecewise<D2<SBasis> > const &M, double tol){
     length-=length.segs.front().at0();
     return length;
 }
+
+/** returns a function giving the arclength at each point in M.
+ \param M the Element.
+ \param tol the maximum error allowed.
+
+*/
 Piecewise<SBasis> 
 Geom::arcLengthSb(D2<SBasis> const &M, double tol){
     return arcLengthSb(Piecewise<D2<SBasis> >(M), tol);
 }
 
+#if 0
 double
 Geom::length(D2<SBasis> const &M,
                  double tol){
@@ -273,9 +322,15 @@ Geom::length(Piecewise<D2<SBasis> > const &M,
     Piecewise<SBasis> length = arcLengthSb(M, tol);
     return length.segs.back().at1();
 }
+#endif
 
+/** returns a function giving the curvature at each point in M.
+ \param M the Element.
+ \param tol the maximum error allowed.
 
-// incomplete.
+ Todo:
+ * claimed incomplete.  Check.
+*/
 Piecewise<SBasis>
 Geom::curvature(D2<SBasis> const &M, double tol) {
     D2<SBasis> dM=derivative(M);
@@ -287,6 +342,13 @@ Geom::curvature(D2<SBasis> const &M, double tol) {
     return(k);
 }
 
+/** returns a function giving the curvature at each point in M.
+ \param M the Element.
+ \param tol the maximum error allowed.
+
+ Todo:
+ * claimed incomplete.  Check.
+*/
 Piecewise<SBasis> 
 Geom::curvature(Piecewise<D2<SBasis> > const &V, double tol){
     Piecewise<SBasis> result;
@@ -303,6 +365,12 @@ Geom::curvature(Piecewise<D2<SBasis> > const &V, double tol){
 
 //=================================================================
 
+/** Reparameterise M to have unit speed.
+ \param M the Element.
+ \param tol the maximum error allowed.
+ \param order the maximum degree to use for approximation
+
+*/
 Piecewise<D2<SBasis> >
 Geom::arc_length_parametrization(D2<SBasis> const &M,
                            unsigned order,
@@ -326,6 +394,12 @@ Geom::arc_length_parametrization(D2<SBasis> const &M,
     return u;
 }
 
+/** Reparameterise M to have unit speed.
+ \param M the Element.
+ \param tol the maximum error allowed.
+ \param order the maximum degree to use for approximation
+
+*/
 Piecewise<D2<SBasis> >
 Geom::arc_length_parametrization(Piecewise<D2<SBasis> > const &M,
                                  unsigned order,
@@ -338,17 +412,83 @@ Geom::arc_length_parametrization(Piecewise<D2<SBasis> > const &M,
     return(result);
 }
 
-/** centroid using sbasis integration.
- * This approach uses green's theorem to compute the area and centroid using integrals.  For curved
- * shapes this is much faster than converting to polyline.
+#include <gsl/gsl_integration.h>
+static double sb_length_integrating(double t, void* param) {
+    SBasis* pc = (SBasis*)param;
+    return sqrt((*pc)(t));
+}
+
+/** Calculates the length of a D2<SBasis> through gsl integration.
+ \param B the Element.
+ \param tol the maximum error allowed.
+ \param result variable to be incremented with the length of the path
+ \param abs_error variable to be incremented with the estimated error
+
+If you only want the length, this routine may be faster/more accurate.
+*/
+void Geom::length_integrating(D2<SBasis> const &B, double &result, double &abs_error, double tol) {
+    D2<SBasis> dB = derivative(B);
+    SBasis dB2 = dot(dB, dB);
+        
+    gsl_function F;
+    gsl_integration_workspace * w 
+        = gsl_integration_workspace_alloc (20);
+    F.function = &sb_length_integrating;
+    F.params = (void*)&dB2;
+    double quad_result, err;
+    /* We could probably use the non adaptive code here if we removed any cusps first. */
+         
+    gsl_integration_qag (&F, 0, 1, 0, tol, 20, 
+                         GSL_INTEG_GAUSS21, w, &quad_result, &err);
+        
+    abs_error += err;
+    result += quad_result;
+}
+
+/** Calculates the length of a D2<SBasis> through gsl integration.
+ \param s the Element.
+ \param tol the maximum error allowed.
+
+If you only want the total length, this routine faster and more accurate than constructing an arcLengthSb.
+*/
+double
+Geom::length(D2<SBasis> const &s,
+                 double tol){
+    double result = 0;
+    double abs_error = 0;
+    length_integrating(s, result, abs_error, tol);
+    return result;
+}
+/** Calculates the length of a Piecewise<D2<SBasis> > through gsl integration.
+ \param s the Element.
+ \param tol the maximum error allowed.
+
+If you only want the total length, this routine faster and more accurate than constructing an arcLengthSb.
+*/
+double
+Geom::length(Piecewise<D2<SBasis> > const &s,
+                 double tol){
+    double result = 0;
+    double abs_error = 0;
+    for (unsigned i=0; i < s.size();i++){
+        length_integrating(s[i], result, abs_error, tol);
+    }
+    return result;
+}
+
+/**
+ * Centroid using sbasis integration.
+ \param p the Element.
+ \param centroid on return contains the centroid of the shape
+ \param area on return contains the signed area of the shape.
+This approach uses green's theorem to compute the area and centroid using integrals.  For curved shapes this is much faster than converting to polyline.  Note that without an uncross operation the output is not the absolute area.
 
  * Returned values: 
     0 for normal execution;
     2 if area is zero, meaning centroid is meaningless.
 
- * Copyright Nathan Hurst 2006
  */
-
 unsigned Geom::centroid(Piecewise<D2<SBasis> > const &p, Point& centroid, double &area) {
     Point centroid_tmp(0,0);
     double atmp = 0;
@@ -374,6 +514,203 @@ unsigned Geom::centroid(Piecewise<D2<SBasis> > const &p, Point& centroid, double
     return 2;
 }
 
+/**
+ * Find cubics with prescribed curvatures at both ends.
+ *
+ *  this requires to solve a system of the form
+ *
+ * \f[
+ *  \lambda_1 = a_0 \lambda_0^2 + c_0
+ *  \lambda_0 = a_1 \lambda_1^2 + c_1
+ * \f]
+ *
+ * which is a deg 4 equation in lambda 0.
+ * Below are basic functions dedicated to solving this assuming a0 and a1 !=0.
+ */
+
+static Interval
+find_bounds_for_lambda0(double aa0,double aa1,double cc0,double cc1,
+    int insist_on_speeds_signs){
+
+    double a0=aa0,a1=aa1,c0=cc0,c1=cc1;
+    Interval result;
+    bool flip = a1<0;
+    if (a1<0){a1=-a1; c1=-c1;}
+    if (a0<0){a0=-a0; c0=-c0;}
+    double a = (a0<a1 ? a0 : a1);
+    double c = (c0<c1 ? c0 : c1);
+    double delta = 1-4*a*c;
+    if ( delta < 0 )
+        return Interval();//return empty interval
+    double lambda_max = (1+std::sqrt(delta))/2/a;
+    
+    result = Interval(c,lambda_max);
+    if (flip) 
+        result *= -1;
+    if (insist_on_speeds_signs == 1){
+        if (result.max() < 0)//Caution: setMin with max<new min...
+            return Interval();//return empty interval
+        result.setMin(0);
+    }
+    return result;
+}
+
+static 
+std::vector<double>
+solve_lambda0(double a0,double a1,double c0,double c1,
+             int insist_on_speeds_signs){
+
+    SBasis p;
+    p.push_back(Linear( a1*c0*c0+c1, a1*a0*(a0+ 2*c0) +a1*c0*c0 +c1 -1  ));
+    p.push_back(Linear( -a1*a0*(a0+2*c0), -a1*a0*(3*a0+2*c0) ));
+    p.push_back(Linear( a1*a0*a0 ));
+
+    Interval domain = find_bounds_for_lambda0(a0,a1,c0,c1,insist_on_speeds_signs);
+    if ( domain.isEmpty() ) 
+        return std::vector<double>();
+    p = compose(p,Linear(domain.min(),domain.max()));
+    std::vector<double>rts = roots(p);
+    for (unsigned i=0; i<rts.size(); i++){
+        rts[i] = domain.min()+rts[i]*domain.extent();
+    }
+    return rts;
+}
+
+/**
+* \brief returns the cubics fitting direction and curvature of a given
+* input curve at two points.
+* 
+* The input can be the 
+*    value, speed, and acceleration
+* or
+*    value, speed, and cross(acceleration,speed) 
+* of the original curve at the both ends.
+* (the second is often technically usefull, as it avoids unnecessary division by |v|^2) 
+* Recall that K=1/R=cross(acceleration,speed)/|speed|^3.
+*
+* Moreover, a 7-th argument 'insist_on_speed_signs' can be supplied to select solutions:  
+* If insist_on_speed_signs == 1, only consider solutions where speeds at both ends are positively
+* proportional to the given ones.
+* If insist_on_speed_signs == 0, allow speeds to point in the opposite direction (both at the same time) 
+* If insist_on_speed_signs == -1, allow speeds to point in both direction independantly. 
+*/
+std::vector<D2<SBasis> >
+Geom::cubics_fitting_curvature(Point const &M0,   Point const &M1,
+                         Point const &dM0,  Point const &dM1,
+                         double d2M0xdM0,  double d2M1xdM1,
+                         int insist_on_speed_signs,
+                         double epsilon){
+    std::vector<D2<SBasis> > result;
+
+    //speed of cubic bezier will be lambda0*dM0 and lambda1*dM1,
+    //with lambda0 and lambda1 s.t. curvature at both ends is the same
+    //as the curvature of the given curve.
+    std::vector<double> lambda0,lambda1;
+    double dM1xdM0=cross(dM1,dM0);
+    if (fabs(dM1xdM0)<epsilon){
+        if (fabs(d2M0xdM0)<epsilon || fabs(d2M1xdM1)<epsilon){
+            return result;
+        }
+        double lbda02 = 6.*cross(M1-M0,dM0)/d2M0xdM0;
+        double lbda12 =-6.*cross(M1-M0,dM1)/d2M1xdM1;
+        if (lbda02<0 || lbda12<0){
+            return result;
+        }
+        lambda0.push_back(std::sqrt(lbda02) );
+        lambda1.push_back(std::sqrt(lbda12) );
+    }else{
+        //solve:  lambda1 = a0 lambda0^2 + c0
+        //        lambda0 = a1 lambda1^2 + c1
+        double a0,c0,a1,c1;
+        a0 = -d2M0xdM0/2/dM1xdM0;
+        c0 =  3*cross(M1-M0,dM0)/dM1xdM0;
+        a1 = -d2M1xdM1/2/dM1xdM0;
+        c1 = -3*cross(M1-M0,dM1)/dM1xdM0;
+
+        if (fabs(a0)<epsilon){
+            lambda1.push_back( c0 );
+            lambda0.push_back( a1*c0*c0 + c1 );
+        }else if (fabs(a1)<epsilon){
+            lambda0.push_back( c1 );
+            lambda1.push_back( a0*c1*c1 + c0 );
+        }else{
+            //find lamda0 by solving a deg 4 equation d0+d1*X+...+d4*X^4=0
+            double a[5];
+            a[0] = c1+a1*c0*c0;
+            a[1] = -1;
+            a[2] = 2*a1*a0*c0;
+            a[3] = 0;
+            a[4] = a1*a0*a0;
+            //vector<double> solns=solve_poly(a,4);
+            vector<double> solns=solve_lambda0(a0,a1,c0,c1,insist_on_speed_signs);
+            for (unsigned i=0;i<solns.size();i++){
+                double lbda0=solns[i];
+                double lbda1=c0+a0*lbda0*lbda0;
+                //is this solution pointing in the + direction at both ends?
+                if (lbda0>=0. && lbda1>=0.){
+                    lambda0.push_back( lbda0);
+                    lambda1.push_back( lbda1);
+                }
+                //is this solution pointing in the - direction at both ends?
+                else if (lbda0<=0. && lbda1<=0. && insist_on_speed_signs<=0){
+                    lambda0.push_back( lbda0);
+                    lambda1.push_back( lbda1);
+                }
+                //ok,this solution is pointing in the + and - directions.
+                else if (insist_on_speed_signs<0){
+                    lambda0.push_back( lbda0);
+                    lambda1.push_back( lbda1);
+                }
+            }
+        }
+    }
+    
+    for (unsigned i=0; i<lambda0.size(); i++){
+        Point V0 = lambda0[i]*dM0;
+        Point V1 = lambda1[i]*dM1;
+        D2<SBasis> cubic;
+        for(unsigned dim=0;dim<2;dim++){
+            cubic[dim] = Linear(M0[dim],M1[dim]);
+            cubic[dim].push_back(Linear( M0[dim]-M1[dim]+V0[dim],
+                                         -M0[dim]+M1[dim]-V1[dim]));
+        }
+#if 0
+           Piecewise<SBasis> k = curvature(result);
+           double dM0_l = dM0.length();
+           double dM1_l = dM1.length();
+           g_warning("Target radii: %f, %f", dM0_l*dM0_l*dM0_l/d2M0xdM0,dM1_l*dM1_l*dM1_l/d2M1xdM1);
+           g_warning("Obtained radii: %f, %f",1/k.valueAt(0),1/k.valueAt(1));
+#endif
+        result.push_back(cubic);
+    }
+    return(result);
+}
+
+std::vector<D2<SBasis> >
+Geom::cubics_fitting_curvature(Point const &M0,   Point const &M1,
+                         Point const &dM0,  Point const &dM1,
+                         Point const &d2M0, Point const &d2M1,
+                         int insist_on_speed_signs,
+                         double epsilon){
+    double d2M0xdM0 = cross(d2M0,dM0);
+    double d2M1xdM1 = cross(d2M1,dM1);
+    return cubics_fitting_curvature(M0,M1,dM0,dM1,d2M0xdM0,d2M1xdM1,insist_on_speed_signs,epsilon);
+}
+
+std::vector<D2<SBasis> >
+Geom::cubics_with_prescribed_curvature(Point const &M0,   Point const &M1,
+                                 Point const &dM0,  Point const &dM1,
+                                 double k0, double k1,
+                                 int insist_on_speed_signs,
+                                 double epsilon){
+    double length;
+    length = dM0.length();
+    double d2M0xdM0 = k0*length*length*length;
+    length = dM1.length();
+    double d2M1xdM1 = k1*length*length*length;
+    return cubics_fitting_curvature(M0,M1,dM0,dM1,d2M0xdM0,d2M1xdM1,insist_on_speed_signs,epsilon);
+}
+
 //}; // namespace
 
 
index 7e067d8013c3abe91468956daa9c27f452c2afeb..18c666b11141b4cd2513fdc12ff8d11ce4ce9955 100644 (file)
@@ -4,7 +4,10 @@
 #include <2geom/piecewise.h>
 #include <vector>
 
-/** two-dimensional geometric operators.  
+/**
+ * \file
+ * \brief two-dimensional geometric operators.  
+ *
  * Copyright 2007, JFBarraud
  * Copyright 2007, njh
  * 
@@ -61,6 +64,8 @@ Piecewise<SBasis> arcLengthSb(Piecewise<D2<SBasis> > const &M, double tol=.01);
 double length(          D2<SBasis>   const &M, double tol=.01);
 double length(Piecewise<D2<SBasis> > const &M, double tol=.01);
 
+void length_integrating(D2<SBasis> const &B, double &result, double &abs_error, double tol);
+
 Piecewise<D2<SBasis> >
 arc_length_parametrization(D2<SBasis> const &M, 
                            unsigned order=3, 
@@ -73,6 +78,27 @@ arc_length_parametrization(Piecewise<D2<SBasis> > const &M,
 
 unsigned centroid(Piecewise<D2<SBasis> > const &p, Point& centroid, double &area);
 
+std::vector<D2<SBasis> >
+cubics_fitting_curvature(Point const &M0,   Point const &M1,
+                         Point const &dM0,  Point const &dM1,
+                         double d2M0xdM0,  double d2M1xdM1,
+                         int insist_on_speed_signs = 1,
+                         double epsilon = 1e-5);
+
+std::vector<D2<SBasis> >
+cubics_fitting_curvature(Point const &M0,   Point const &M1,
+                         Point const &dM0,  Point const &dM1,
+                         Point const &d2M0, Point const &d2M1,
+                         int insist_on_speed_signs = 1,
+                         double epsilon = 1e-5);
+
+std::vector<D2<SBasis> >
+cubics_with_prescribed_curvature(Point const &M0,   Point const &M1,
+                                 Point const &dM0,  Point const &dM1,
+                                 double k0,         double k1,
+                                 int insist_on_speed_signs = 1,
+                                 double error = 1e-5);
+
 };
 
 #endif
index f5a8ab7a10207768724e4e93cf86b868a5621495..1d179a5630ec2dbc7436b536eecf1447b383a47d 100644 (file)
@@ -45,9 +45,15 @@ namespace Geom {
 #include <math.h>
 
 //-|x|-----------------------------------------------------------------------
+/** Return the absolute value of a function pointwise.
+ \param f function
+*/
 Piecewise<SBasis> abs(SBasis const &f){
     return abs(Piecewise<SBasis>(f));
 }
+/** Return the absolute value of a function pointwise.
+ \param f function
+*/
 Piecewise<SBasis> abs(Piecewise<SBasis> const &f){
     Piecewise<SBasis> absf=partition(f,roots(f));
     for (unsigned i=0; i<absf.size(); i++){
@@ -57,15 +63,27 @@ Piecewise<SBasis> abs(Piecewise<SBasis> const &f){
 }
 
 //-max(x,y), min(x,y)--------------------------------------------------------
+/** Return the greater of the two functions pointwise.
+ \param f, g two functions
+*/
 Piecewise<SBasis> max(          SBasis  const &f,           SBasis  const &g){
     return max(Piecewise<SBasis>(f),Piecewise<SBasis>(g));
 }
+/** Return the greater of the two functions pointwise.
+ \param f, g two functions
+*/
 Piecewise<SBasis> max(Piecewise<SBasis> const &f,           SBasis  const &g){
     return max(f,Piecewise<SBasis>(g));
 }
+/** Return the greater of the two functions pointwise.
+ \param f, g two functions
+*/
 Piecewise<SBasis> max(          SBasis  const &f, Piecewise<SBasis> const &g){
     return max(Piecewise<SBasis>(f),g);
 }
+/** Return the greater of the two functions pointwise.
+ \param f, g two functions
+*/
 Piecewise<SBasis> max(Piecewise<SBasis> const &f, Piecewise<SBasis> const &g){
     Piecewise<SBasis> max=partition(f,roots(f-g));
     Piecewise<SBasis> gg =partition(g,max.cuts);
@@ -76,20 +94,38 @@ Piecewise<SBasis> max(Piecewise<SBasis> const &f, Piecewise<SBasis> const &g){
     return max;
 }
 
+/** Return the more negative of the two functions pointwise.
+ \param f, g two functions
+*/
 Piecewise<SBasis> 
 min(          SBasis  const &f,           SBasis  const &g){ return -max(-f,-g); }
+/** Return the more negative of the two functions pointwise.
+ \param f, g two functions
+*/
 Piecewise<SBasis> 
 min(Piecewise<SBasis> const &f,           SBasis  const &g){ return -max(-f,-g); }
+/** Return the more negative of the two functions pointwise.
+ \param f, g two functions
+*/
 Piecewise<SBasis> 
 min(          SBasis  const &f, Piecewise<SBasis> const &g){ return -max(-f,-g); }
+/** Return the more negative of the two functions pointwise.
+ \param f, g two functions
+*/
 Piecewise<SBasis> 
 min(Piecewise<SBasis> const &f, Piecewise<SBasis> const &g){ return -max(-f,-g); }
 
 
 //-sign(x)---------------------------------------------------------------
+/** Return the sign of the two functions pointwise.
+ \param f function
+*/
 Piecewise<SBasis> signSb(SBasis const &f){
     return signSb(Piecewise<SBasis>(f));
 }
+/** Return the sign of the two functions pointwise.
+ \param f function
+*/
 Piecewise<SBasis> signSb(Piecewise<SBasis> const &f){
     Piecewise<SBasis> sign=partition(f,roots(f));
     for (unsigned i=0; i<sign.size(); i++){
@@ -139,10 +175,16 @@ static Piecewise<SBasis> sqrt_internal(SBasis const &f,
     return sqrtf0;
 }
 
+/** Compute the sqrt of a function.
+ \param f function
+*/
 Piecewise<SBasis> sqrt(SBasis const &f, double tol, int order){
     return sqrt(max(f,Linear(tol*tol)),tol,order);
 }
 
+/** Compute the sqrt of a function.
+ \param f function
+*/
 Piecewise<SBasis> sqrt(Piecewise<SBasis> const &f, double tol, int order){
     Piecewise<SBasis> result;
     Piecewise<SBasis> zero = Piecewise<SBasis>(Linear(tol*tol));
@@ -159,9 +201,24 @@ Piecewise<SBasis> sqrt(Piecewise<SBasis> const &f, double tol, int order){
 
 //-Yet another sin/cos--------------------------------------------------------------
 
+/** Compute the sine of a function.
+ \param f function
+ \param tol maximum error
+ \param order maximum degree polynomial to use
+*/
 Piecewise<SBasis> sin(          SBasis  const &f, double tol, int order){return(cos(-f+M_PI/2,tol,order));}
+/** Compute the sine of a function.
+ \param f function
+ \param tol maximum error
+ \param order maximum degree polynomial to use
+*/
 Piecewise<SBasis> sin(Piecewise<SBasis> const &f, double tol, int order){return(cos(-f+M_PI/2,tol,order));}
 
+/** Compute the cosine of a function.
+ \param f function
+ \param tol maximum error
+ \param order maximum degree polynomial to use
+*/
 Piecewise<SBasis> cos(Piecewise<SBasis> const &f, double tol, int order){
     Piecewise<SBasis> result;
     for (unsigned i=0; i<f.size(); i++){
@@ -172,6 +229,11 @@ Piecewise<SBasis> cos(Piecewise<SBasis> const &f, double tol, int order){
     return result;
 }
 
+/** Compute the cosine of a function.
+ \param f function
+ \param tol maximum error
+ \param order maximum degree polynomial to use
+*/
 Piecewise<SBasis> cos(          SBasis  const &f, double tol, int order){
     double alpha = (f.at0()+f.at1())/2.;
     SBasis x = f-alpha;
index 2a51bffb3fdd048ad297ce2667d4c802f0e87843..053c2d285c7ab360c03aae02c8d813028bfeee23 100644 (file)
@@ -1,5 +1,6 @@
-/*
- *  sbasis-math.h - some std functions to work with (pw)s-basis
+/**
+ * \file
+ * \brief some std functions to work with (pw)s-basis
  *
  *  Authors:
  *   Jean-Francois Barraud
index 3fee0afe4e6b1796c98fe393026cbdd0cf507e62..ec632d5a2e7a81376b61dcb4276c83414e79c14c 100644 (file)
@@ -2,6 +2,12 @@
 
 namespace Geom{
 
+/** Changes the basis of p to be sbasis.
+ \param p the Monomial basis polynomial
+ \returns the Symmetric basis polynomial
+
+This algorithm is horribly slow and numerically terrible.  Only for testing.
+*/
 SBasis poly_to_sbasis(Poly const & p) {
     SBasis x = Linear(0, 1);
     SBasis r;
@@ -14,6 +20,12 @@ SBasis poly_to_sbasis(Poly const & p) {
        
 }
 
+/** Changes the basis of p to be monomial.
+ \param p the Symmetric basis polynomial
+ \returns the Monomial basis polynomial
+
+This algorithm is horribly slow and numerically terrible.  Only for testing.
+*/
 Poly sbasis_to_poly(SBasis const & sb) {
     if(sb.isZero())
         return Poly();
index 09c8e54870f7928c7f576de6902923293996c00c..1c509cf845bd60f0012b056f3404233d3a9f22af 100644 (file)
@@ -4,8 +4,38 @@
 #include <2geom/poly.h>
 #include <2geom/sbasis.h>
 
-/*** Conversion between SBasis and Poly.  Not recommended for general
- * use due to instability.
+/**
+ * \file
+ * \brief Conversion between SBasis and Poly.  Not recommended for general use due to instability.
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
  */
 
 namespace Geom{
index 09a84050bbd8cb622f0a0e4b0ce28c74a5b13c39..2eb1e4cbbb86b6059e00c641af11f9f38030dd6d 100644 (file)
@@ -52,6 +52,11 @@ using namespace std;
 
 namespace Geom{
 
+/** Find the smallest interval that bounds a
+ \param a sbasis function
+ \returns inteval
+
+*/
 Interval bounds_exact(SBasis const &a) {
     Interval result = Interval(a.at0(), a.at1());
     SBasis df = derivative(a);
@@ -62,6 +67,11 @@ Interval bounds_exact(SBasis const &a) {
     return result;
 }
 
+/** Find a small interval that bounds a
+ \param a sbasis function
+ \returns inteval
+
+*/
 // I have no idea how this works, some clever bounding argument by jfb.
 Interval bounds_fast(const SBasis &sb, int order) {
     Interval res(0,0); // an empty sbasis is 0.
@@ -91,6 +101,13 @@ Interval bounds_fast(const SBasis &sb, int order) {
     return res;
 }
 
+/** Find a small interval that bounds a(t) for t in i to order order
+ \param sb sbasis function
+ \param i domain interval
+ \param order number of terms
+ \returns inteval
+
+*/
 Interval bounds_local(const SBasis &sb, const Interval &i, int order) {
     double t0=i.min(), t1=i.max(), lo=0., hi=0.;
     for(int j = sb.size()-1; j>=order; j--) {
@@ -246,6 +263,29 @@ static void multi_roots_internal(SBasis const &f,
     }
 }
 
+/** Solve f(t)=c for several c at once.
+    \param f sbasis function
+    \param levels vector of 'y' values
+    \param htol, vtol 
+    \param a, b left and right bounds
+    \returns a vector of vectors, one for each y giving roots
+
+Effectively computes:
+results = roots(f(y_i)) for all y_i
+
+* algo: -compute f at both ends of the given segment [a,b].
+         -compute bounds m<df(t)<M for df on the segment.
+         let c and C be the levels below and above f(a):
+         going from f(a) down to c with slope m takes at least time (f(a)-c)/m
+         going from f(a)  up  to C with slope M takes at least time (C-f(a))/M
+         From this we conclude there are no roots before a'=a+min((f(a)-c)/m,(C-f(a))/M).
+         Do the same for b: compute some b' such that there are no roots in (b',b].
+         -if [a',b'] is not empty, repeat the process with [a',(a'+b')/2] and [(a'+b')/2,b'].
+  unfortunately, extra care is needed about rounding errors, and also to avoid the repetition of roots,
+  making things tricky and unpleasant...
+
+TODO: Make sure the code is "rounding-errors proof" and take care about repetition of roots!
+*/
 std::vector<std::vector<double> > multi_roots(SBasis const &f,
                                       std::vector<double> const &levels,
                                       double htol,
@@ -262,57 +302,6 @@ std::vector<std::vector<double> > multi_roots(SBasis const &f,
 }
 //-------------------------------------
 
-#if 0
-double Laguerre_internal(SBasis const & p,
-                         double x0,
-                         double tol,
-                         bool & quad_root) {
-    double a = 2*tol;
-    double xk = x0;
-    double n = p.size();
-    quad_root = false;
-    while(a > tol) {
-        //std::cout << "xk = " << xk << std::endl;
-        Linear b = p.back();
-        Linear d(0), f(0);
-        double err = fabs(b);
-        double abx = fabs(xk);
-        for(int j = p.size()-2; j >= 0; j--) {
-            f = xk*f + d;
-            d = xk*d + b;
-            b = xk*b + p[j];
-            err = fabs(b) + abx*err;
-        }
-
-        err *= 1e-7; // magic epsilon for convergence, should be computed from tol
-
-        double px = b;
-        if(fabs(b) < err)
-            return xk;
-        //if(std::norm(px) < tol*tol)
-        //    return xk;
-        double G = d / px;
-        double H = G*G - f / px;
-
-        //std::cout << "G = " << G << "H = " << H;
-        double radicand = (n - 1)*(n*H-G*G);
-        //assert(radicand.real() > 0);
-        if(radicand < 0)
-            quad_root = true;
-        //std::cout << "radicand = " << radicand << std::endl;
-        if(G.real() < 0) // here we try to maximise the denominator avoiding cancellation
-            a = - std::sqrt(radicand);
-        else
-            a = std::sqrt(radicand);
-        //std::cout << "a = " << a << std::endl;
-        a = n / (a + G);
-        //std::cout << "a = " << a << std::endl;
-        xk -= a;
-    }
-    //std::cout << "xk = " << xk << std::endl;
-    return xk;
-}
-#endif
 
 void subdiv_sbasis(SBasis const & s,
                    std::vector<double> & roots,
@@ -343,6 +332,11 @@ std::vector<double> roots1(SBasis const & s) {
     return res;
 }
 
+/** Find all t s.t s(t) = 0
+ \param a sbasis function
+ \returns vector of zeros (roots)
+
+*/
 std::vector<double> roots(SBasis const & s) {
     switch(s.size()) {
         case 0:
index 27e3047fd1beae5cc226713fb8f60be36da6a40d..dfb24f9d90275a423d0fd773b2e039bb3540e62a 100644 (file)
@@ -33,6 +33,7 @@
 
 
 #include <2geom/sbasis-to-bezier.h>
+#include <2geom/d2.h>
 #include <2geom/choose.h>
 #include <2geom/svg-path.h>
 #include <2geom/exception.h>
@@ -87,11 +88,16 @@ int sgn(unsigned int j, unsigned int k)
 }
 
 
+/** Changes the basis of p to be bernstein.
+ \param p the Symmetric basis polynomial
+ \returns the Bernstein basis polynomial
+
+ if the degree is even q is the order in the symmetrical power basis,
+ if the degree is odd q is the order + 1
+ n is always the polynomial degree, i. e. the Bezier order
+*/
 void sbasis_to_bezier (Bezier & bz, SBasis const& sb, size_t sz)
 {
-    // if the degree is even q is the order in the symmetrical power basis,
-    // if the degree is odd q is the order + 1
-    // n is always the polynomial degree, i. e. the Bezier order
     size_t q, n;
     bool even;
     if (sz == 0)
@@ -141,6 +147,14 @@ void sbasis_to_bezier (Bezier & bz, SBasis const& sb, size_t sz)
     bz[n] = sb[0][1];
 }
 
+/** Changes the basis of p to be Bernstein.
+ \param p the D2 Symmetric basis polynomial
+ \returns the D2 Bernstein basis polynomial
+
+ if the degree is even q is the order in the symmetrical power basis,
+ if the degree is odd q is the order + 1
+ n is always the polynomial degree, i. e. the Bezier order
+*/
 void sbasis_to_bezier (std::vector<Point> & bz, D2<SBasis> const& sb, size_t sz)
 {
     Bezier bzx, bzy;
@@ -160,11 +174,16 @@ void sbasis_to_bezier (std::vector<Point> & bz, D2<SBasis> const& sb, size_t sz)
 }
 
 
+/** Changes the basis of p to be sbasis.
+ \param p the Bernstein basis polynomial
+ \returns the Symmetric basis polynomial
+
+ if the degree is even q is the order in the symmetrical power basis,
+ if the degree is odd q is the order + 1
+ n is always the polynomial degree, i. e. the Bezier order
+*/
 void bezier_to_sbasis (SBasis & sb, Bezier const& bz)
 {
-    // if the degree is even q is the order in the symmetrical power basis,
-    // if the degree is odd q is the order + 1
-    // n is always the polynomial degree, i. e. the Bezier order
     size_t n = bz.order();
     size_t q = (n+1) / 2;
     size_t even = (n & 1u) ? 0 : 1;
@@ -201,6 +220,14 @@ void bezier_to_sbasis (SBasis & sb, Bezier const& bz)
 }
 
 
+/** Changes the basis of d2 p to be sbasis.
+ \param p the d2 Bernstein basis polynomial
+ \returns the d2 Symmetric basis polynomial
+
+ if the degree is even q is the order in the symmetrical power basis,
+ if the degree is odd q is the order + 1
+ n is always the polynomial degree, i. e. the Bezier order
+*/
 void bezier_to_sbasis (D2<SBasis> & sb, std::vector<Point> const& bz)
 {
     size_t n = bz.size() - 1;
@@ -252,138 +279,8 @@ void bezier_to_sbasis (D2<SBasis> & sb, std::vector<Point> const& bz)
 
 }  // end namespace Geom
 
-namespace Geom{
-#if 0
-
-/* From Sanchez-Reyes 1997
-   W_{j,k} = W_{n0j, n-k} = choose(n-2k-1, j-k)choose(2k+1,k)/choose(n,j)
-     for k=0,...,q-1; j = k, ...,n-k-1
-   W_{q,q} = 1 (n even)
-
-This is wrong, it should read
-   W_{j,k} = W_{n0j, n-k} = choose(n-2k-1, j-k)/choose(n,j)
-     for k=0,...,q-1; j = k, ...,n-k-1
-   W_{q,q} = 1 (n even)
-
-*/
-double W(unsigned n, unsigned j, unsigned k) {
-    unsigned q = (n+1)/2;
-    if((n & 1) == 0 && j == q && k == q)
-        return 1;
-    if(k > n-k) return W(n, n-j, n-k);
-    assert((k <= q));
-    if(k >= q) return 0;
-    //assert(!(j >= n-k));
-    if(j >= n-k) return 0;
-    //assert(!(j < k));
-    if(j < k) return 0;
-    return choose<double>(n-2*k-1, j-k) /
-        choose<double>(n,j);
-}
-
-
-// this produces a degree 2q bezier from a degree k sbasis
-Bezier
-sbasis_to_bezier(SBasis const &B, unsigned q) {
-    if(q == 0) {
-        q = B.size();
-        /*if(B.back()[0] == B.back()[1]) {
-            n--;
-            }*/
-    }
-    unsigned n = q*2;
-    Bezier result = Bezier(Bezier::Order(n-1));
-    if(q > B.size())
-        q = B.size();
-    n--;
-    for(unsigned k = 0; k < q; k++) {
-        for(unsigned j = 0; j <= n-k; j++) {
-            result[j] += (W(n, j, k)*B[k][0] +
-                          W(n, n-j, k)*B[k][1]);
-        }
-    }
-    return result;
-}
-
-double mopi(int i) {
-    return (i&1)?-1:1;
-}
-
-// WARNING: this is wrong!
-// this produces a degree k sbasis from a degree 2q bezier
-SBasis
-bezier_to_sbasis(Bezier const &B) {
-    unsigned n = B.size();
-    unsigned q = (n+1)/2;
-    SBasis result;
-    result.resize(q+1);
-    for(unsigned k = 0; k < q; k++) {
-        result[k][0] = result[k][1] = 0;
-        for(unsigned j = 0; j <= n-k; j++) {
-            result[k][0] += mopi(int(j)-int(k))*W(n, j, k)*B[j];
-            result[k][1] += mopi(int(j)-int(k))*W(n, j, k)*B[j];
-            //W(n, n-j, k)*B[k][1]);
-        }
-    }
-    return result;
-}
-
-// this produces a 2q point bezier from a degree q sbasis
-std::vector<Geom::Point>
-sbasis_to_bezier(D2<SBasis> const &B, unsigned qq) {
-    std::vector<Geom::Point> result;
-    if(qq == 0) {
-        qq = sbasis_size(B);
-    }
-    unsigned n = qq * 2;
-    result.resize(n, Geom::Point(0,0));
-    n--;
-    for(unsigned dim = 0; dim < 2; dim++) {
-        unsigned q = qq;
-        if(q > B[dim].size())
-            q = B[dim].size();
-        for(unsigned k = 0; k < q; k++) {
-            for(unsigned j = 0; j <= n-k; j++) {
-                result[j][dim] += (W(n, j, k)*B[dim][k][0] +
-                             W(n, n-j, k)*B[dim][k][1]);
-                }
-        }
-    }
-    return result;
-}
-/*
-template <unsigned order>
-D2<Bezier<order> > sbasis_to_bezier(D2<SBasis> const &B) {
-    return D2<Bezier<order> >(sbasis_to_bezier<order>(B[0]), sbasis_to_bezier<order>(B[1]));
-}
-*/
-#endif
-
-#if 0 // using old path
-//std::vector<Geom::Point>
-// mutating
-void
-subpath_from_sbasis(Geom::OldPathSetBuilder &pb, D2<SBasis> const &B, double tol, bool initial) {
-    assert(B.IS_FINITE());
-    if(B.tail_error(2) < tol || B.size() == 2) { // nearly cubic enough
-        if(B.size() == 1) {
-            if (initial) {
-                pb.start_subpath(Geom::Point(B[0][0][0], B[1][0][0]));
-            }
-            pb.push_line(Geom::Point(B[0][0][1], B[1][0][1]));
-        } else {
-            std::vector<Geom::Point> bez = sbasis_to_bezier(B, 2);
-            if (initial) {
-                pb.start_subpath(bez[0]);
-            }
-            pb.push_cubic(bez[1], bez[2], bez[3]);
-        }
-    } else {
-        subpath_from_sbasis(pb, compose(B, Linear(0, 0.5)), tol, initial);
-        subpath_from_sbasis(pb, compose(B, Linear(0.5, 1)), tol, false);
-    }
-}
 
+#if 0 
 /*
 * This version works by inverting a reasonable upper bound on the error term after subdividing the
 * curve at $a$.  We keep biting off pieces until there is no more curve left.
@@ -431,9 +328,14 @@ subpath_from_sbasis_incremental(Geom::OldPathSetBuilder &pb, D2<SBasis> B, doubl
 
 #endif
 
-/*
- * If only_cubicbeziers is true, the resulting path may only contain CubicBezier curves.
- */
+namespace Geom{
+
+/** Make a path from a d2 sbasis.
+ \param p the d2 Symmetric basis polynomial
+ \returns a Path
+
+  If only_cubicbeziers is true, the resulting path may only contain CubicBezier curves.
+*/
 void build_from_sbasis(Geom::PathBuilder &pb, D2<SBasis> const &B, double tol, bool only_cubicbeziers) {
     if (!B.isFinite()) {
         THROW_EXCEPTION("assertion failed: B.isFinite()");
@@ -452,9 +354,12 @@ void build_from_sbasis(Geom::PathBuilder &pb, D2<SBasis> const &B, double tol, b
     }
 }
 
-/*
- * If only_cubicbeziers is true, the resulting path may only contain CubicBezier curves.
- */
+/** Make a path from a d2 sbasis.
+ \param p the d2 Symmetric basis polynomial
+ \returns a Path
+
+  If only_cubicbeziers is true, the resulting path may only contain CubicBezier curves.
+*/
 Path
 path_from_sbasis(D2<SBasis> const &B, double tol, bool only_cubicbeziers) {
     PathBuilder pb;
@@ -464,10 +369,13 @@ path_from_sbasis(D2<SBasis> const &B, double tol, bool only_cubicbeziers) {
     return pb.peek().front();
 }
 
-/*
- * If only_cubicbeziers is true, the resulting path may only contain CubicBezier curves.
- */
-//TODO: some of this logic should be lifted into svg-path
+/** Make a path from a d2 sbasis.
+ \param p the d2 Symmetric basis polynomial
+ \returns a Path
+
+  If only_cubicbeziers is true, the resulting path may only contain CubicBezier curves.
+ TODO: some of this logic should be lifted into svg-path
+*/
 std::vector<Geom::Path>
 path_from_piecewise(Geom::Piecewise<Geom::D2<Geom::SBasis> > const &B, double tol, bool only_cubicbeziers) {
     Geom::PathBuilder pb;
index c9d5cbbbca1973b8288a88dbfb059ccfb1b0263f..2875ab3f0e59f034662d6c5be5798bbdde771c2d 100644 (file)
@@ -1,3 +1,37 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
 #ifndef _SBASIS_TO_BEZIER
 #define _SBASIS_TO_BEZIER
 
index a7e049defa8dd11aae07f8c0493d6559386b7059..2619da594757d755f3751332db91529bc7e0f241 100644 (file)
 
 namespace Geom{
 
-/*** At some point we should work on tighter bounds for the error.  It is clear that the error is
- * bounded by the L1 norm over the tail of the series, but this is very loose, leading to far too
- * many cubic beziers.  I've changed this to be \sum _i=tail ^\infty |hat a_i| 2^-i but I have no
- * evidence that this is correct.
- */
-
-/*
-double SBasis::tail_error(unsigned tail) const {
-    double err = 0, s = 1./(1<<(2*tail)); // rough
-    for(unsigned i = tail; i < size(); i++) {
-        err += (fabs((*this)[i][0]) + fabs((*this)[i][1]))*s;
-        s /= 4;
-    }
-    return err;
-}
+/** bound the error from term truncation
+ \param tail first term to chop
+ \returns the largest possible error this truncation could give
 */
-
 double SBasis::tailError(unsigned tail) const {
   Interval bs = bounds_fast(*this, tail);
   return std::max(fabs(bs.min()),fabs(bs.max()));
 }
 
+/** test all coefficients are finite
+*/
 bool SBasis::isFinite() const {
     for(unsigned i = 0; i < size(); i++) {
         if(!(*this)[i].isFinite())
@@ -68,18 +57,30 @@ bool SBasis::isFinite() const {
     return true;
 }
 
+/** Compute the value and the first n derivatives
+ \param t position to evaluate
+ \param n number of derivatives (not counting value)
+ \returns a vector with the value and the n derivative evaluations
+
+There is an elegant way to compute the value and n derivatives for a polynomial using a variant of horner's rule.  Someone will someday work out how for sbasis.
+*/
 std::vector<double> SBasis::valueAndDerivatives(double t, unsigned n) const {
-    std::vector<double> ret(n+1);
-    ret[0]=valueAt(t);
+    std::vector<double> ret(n);
+    ret.push_back(valueAt(t));
     SBasis tmp = *this;
-    for(unsigned i = 1; i < n+1; i++) {
+    for(unsigned i = 0; i < n; i++) {
         tmp.derive();
-        ret[i] = tmp.valueAt(t);
+        ret[i+1] = tmp.valueAt(t);
     }
     return ret;
 }
 
 
+/** Compute the pointwise sum of a and b (Exact)
+ \param a,b sbasis functions
+ \returns sbasis equal to a+b
+
+*/
 SBasis operator+(const SBasis& a, const SBasis& b) {
     SBasis result;
     const unsigned out_size = std::max(a.size(), b.size());
@@ -98,6 +99,11 @@ SBasis operator+(const SBasis& a, const SBasis& b) {
     return result;
 }
 
+/** Compute the pointwise difference of a and b (Exact)
+ \param a,b sbasis functions
+ \returns sbasis equal to a-b
+
+*/
 SBasis operator-(const SBasis& a, const SBasis& b) {
     SBasis result;
     const unsigned out_size = std::max(a.size(), b.size());
@@ -116,6 +122,11 @@ SBasis operator-(const SBasis& a, const SBasis& b) {
     return result;
 }
 
+/** Compute the pointwise sum of a and b and store in a (Exact)
+ \param a,b sbasis functions
+ \returns sbasis equal to a+b
+
+*/
 SBasis& operator+=(SBasis& a, const SBasis& b) {
     const unsigned out_size = std::max(a.size(), b.size());
     const unsigned min_size = std::min(a.size(), b.size());
@@ -130,6 +141,11 @@ SBasis& operator+=(SBasis& a, const SBasis& b) {
     return a;
 }
 
+/** Compute the pointwise difference of a and b and store in a (Exact)
+ \param a,b sbasis functions
+ \returns sbasis equal to a-b
+
+*/
 SBasis& operator-=(SBasis& a, const SBasis& b) {
     const unsigned out_size = std::max(a.size(), b.size());
     const unsigned min_size = std::min(a.size(), b.size());
@@ -144,6 +160,11 @@ SBasis& operator-=(SBasis& a, const SBasis& b) {
     return a;
 }
 
+/** Compute the pointwise product of a and b (Exact)
+ \param a,b sbasis functions
+ \returns sbasis equal to a*b
+
+*/
 SBasis operator*(SBasis const &a, double k) {
     SBasis c;
     c.reserve(a.size());
@@ -152,6 +173,11 @@ SBasis operator*(SBasis const &a, double k) {
     return c;
 }
 
+/** Compute the pointwise product of a and b and store the value in a (Exact)
+ \param a,b sbasis functions
+ \returns sbasis equal to a*b
+
+*/
 SBasis& operator*=(SBasis& a, double b) {
     if (a.isZero()) return a;
     if (b == 0)
@@ -162,6 +188,12 @@ SBasis& operator*=(SBasis& a, double b) {
     return a;
 }
 
+/** multiply a by x^sh in place (Exact)
+ \param a sbasis function
+ \param sh power
+ \returns a
+
+*/
 SBasis shift(SBasis const &a, int sh) {
     SBasis c = a;
     if(sh > 0) {
@@ -172,6 +204,12 @@ SBasis shift(SBasis const &a, int sh) {
     return c;
 }
 
+/** multiply a by x^sh  (Exact)
+ \param a linear function
+ \param sh power
+ \returns a* x^sh 
+
+*/
 SBasis shift(Linear const &a, int sh) {
     SBasis c;
     if(sh > 0) {
@@ -208,6 +246,12 @@ SBasis multiply(SBasis const &a, SBasis const &b) {
 }
 #else
 
+/** Compute the pointwise product of a and b adding c (Exact)
+ \param a,b,c sbasis functions
+ \returns sbasis equal to a*b+c
+
+The added term is almost free
+*/
 SBasis multiply_add(SBasis const &a, SBasis const &b, SBasis c) {
     if(a.isZero() || b.isZero())
         return c;
@@ -229,6 +273,11 @@ SBasis multiply_add(SBasis const &a, SBasis const &b, SBasis c) {
     return c;
 }
 
+/** Compute the pointwise product of a and b (Exact)
+ \param a,b sbasis functions
+ \returns sbasis equal to a*b
+
+*/
 SBasis multiply(SBasis const &a, SBasis const &b) {
     SBasis c;
     if(a.isZero() || b.isZero())
@@ -236,6 +285,11 @@ SBasis multiply(SBasis const &a, SBasis const &b) {
     return multiply_add(a, b, c);
 }
 #endif 
+/** Compute the integral of a (Exact)
+ \param a sbasis functions
+ \returns sbasis integral(a)
+
+*/
 SBasis integral(SBasis const &c) {
     SBasis a;
     a.resize(c.size() + 1, Linear(0,0));
@@ -255,6 +309,11 @@ SBasis integral(SBasis const &c) {
     return a;
 }
 
+/** Compute the derivative of a (Exact)
+ \param a sbasis functions
+ \returns sbasis da/dt
+
+*/
 SBasis derivative(SBasis const &a) {
     SBasis c;
     c.resize(a.size(), Linear(0,0));
@@ -279,6 +338,9 @@ SBasis derivative(SBasis const &a) {
     return c;
 }
 
+/** Compute the derivative of this inplace (Exact)
+
+*/
 void SBasis::derive() { // in place version
     if(isZero()) return;
     for(unsigned k = 0; k < size()-1; k++) {
@@ -297,7 +359,13 @@ void SBasis::derive() { // in place version
     }
 }
 
-//TODO: convert int k to unsigned k, and remove cast
+/** Compute the sqrt of a
+ \param a sbasis functions
+ \returns sbasis \f[ \sqrt{a} \f]
+
+It is recommended to use the piecewise version unless you have good reason.
+TODO: convert int k to unsigned k, and remove cast
+*/
 SBasis sqrt(SBasis const &a, int k) {
     SBasis c;
     if(a.isZero() || k == 0)
@@ -319,7 +387,12 @@ SBasis sqrt(SBasis const &a, int k) {
     return c;
 }
 
-// return a kth order approx to 1/a)
+/** Compute the recpirocal of a
+ \param a sbasis functions
+ \returns sbasis 1/a
+
+It is recommended to use the piecewise version unless you have good reason.
+*/
 SBasis reciprocal(Linear const &a, int k) {
     SBasis c;
     assert(!a.isZero());
@@ -333,6 +406,12 @@ SBasis reciprocal(Linear const &a, int k) {
     return c;
 }
 
+/** Compute  a / b to k terms
+ \param a,b sbasis functions
+ \returns sbasis a/b
+
+It is recommended to use the piecewise version unless you have good reason.
+*/
 SBasis divide(SBasis const &a, SBasis const &b, int k) {
     SBasis c;
     assert(!a.isZero());
@@ -354,8 +433,12 @@ SBasis divide(SBasis const &a, SBasis const &b, int k) {
     return c;
 }
 
-// a(b)
-// return a0 + s(a1 + s(a2 +...  where s = (1-u)u; ak =(1 - u)a^0_k + ua^1_k
+/** Compute  a composed with b
+ \param a,b sbasis functions
+ \returns sbasis a(b(t))
+
+ return a0 + s(a1 + s(a2 +...  where s = (1-u)u; ak =(1 - u)a^0_k + ua^1_k
+*/
 SBasis compose(SBasis const &a, SBasis const &b) {
     SBasis s = multiply((SBasis(Linear(1,1))-b), b);
     SBasis r;
@@ -366,8 +449,12 @@ SBasis compose(SBasis const &a, SBasis const &b) {
     return r;
 }
 
-// a(b)
-// return a0 + s(a1 + s(a2 +...  where s = (1-u)u; ak =(1 - u)a^0_k + ua^1_k
+/** Compute  a composed with b to k terms
+ \param a,b sbasis functions
+ \returns sbasis a(b(t))
+
+ return a0 + s(a1 + s(a2 +...  where s = (1-u)u; ak =(1 - u)a^0_k + ua^1_k
+*/
 SBasis compose(SBasis const &a, SBasis const &b, unsigned k) {
     SBasis s = multiply((SBasis(Linear(1,1))-b), b);
     SBasis r;
@@ -394,9 +481,14 @@ endfor
 
 //#define DEBUG_INVERSION 1
 
+/** find the function a^-1 such that a^-1 composed with a to k terms is the identity function
+ \param a sbasis function
+ \returns sbasis a^-1 s.t. a^-1(a(t)) = 1
+
+ The function must have 'unit range'("a00 = 0 and a01 = 1") and be monotonic.
+*/
 SBasis inverse(SBasis a, int k) {
     assert(a.size() > 0);
-// the function should have 'unit range'("a00 = 0 and a01 = 1") and be monotonic.
     double a0 = a[0][0];
     if(a0 != 0) {
         a -= a0;
@@ -467,6 +559,12 @@ SBasis inverse(SBasis a, int k) {
     return c;
 }
 
+/** Compute the sine of a to k terms
+ \param b linear function
+ \returns sbasis sin(a)
+
+It is recommended to use the piecewise version unless you have good reason.
+*/
 SBasis sin(Linear b, int k) {
     SBasis s = Linear(std::sin(b[0]), std::sin(b[1]));
     Tri tr(s[0]);
@@ -486,15 +584,26 @@ SBasis sin(Linear b, int k) {
     return s;
 }
 
+/** Compute the cosine of a
+ \param b linear function
+ \returns sbasis cos(a)
+
+It is recommended to use the piecewise version unless you have good reason.
+*/
 SBasis cos(Linear bo, int k) {
     return sin(Linear(bo[0] + M_PI/2,
                       bo[1] + M_PI/2),
                k);
 }
 
-//compute fog^-1. ("zero" = double comparison threshold. *!*we might divide by "zero"*!*)
-//TODO: compute order according to tol?
-//TODO: requires g(0)=0 & g(1)=1 atm... adaptation to other cases should be obvious!
+/** compute fog^-1.
+ \param f,g sbasis functions
+ \returns sbasis f(g^-1(t)).
+
+("zero" = double comparison threshold. *!*we might divide by "zero"*!*)
+TODO: compute order according to tol?
+TODO: requires g(0)=0 & g(1)=1 atm... adaptation to other cases should be obvious!
+*/
 SBasis compose_inverse(SBasis const &f, SBasis const &g, unsigned order, double zero){
     SBasis result; //result
     SBasis r=f; //remainder
index a9939f92a8a2e525d77d65d88acf6d816394e3ff..72bf422e77dc1de9a7fac179ec8d0fac2b50b4bd 100644 (file)
@@ -1,5 +1,6 @@
-/*
- *  sbasis.h - S-power basis function class
+/**
+ * \file
+ * \brief Defines S-power basis function class
  *
  *  Authors:
  *   Nathan Hurst <njh@mail.csse.monash.edu.au>
@@ -138,6 +139,11 @@ Interval bounds_exact(SBasis const &a);
 Interval bounds_fast(SBasis const &a, int order = 0);
 Interval bounds_local(SBasis const &a, const Interval &t, int order = 0);
 
+/** Returns a function which reverses the domain of a.
+ \param a sbasis function
+
+useful for reversing a parameteric curve.
+*/
 inline SBasis reverse(SBasis const &a) {
     SBasis result;
     result.reserve(a.size());
@@ -257,7 +263,11 @@ inline SBasis& operator*=(SBasis& a, SBasis const & b) {
     return a;
 }
 
-//valuation: degree of the first non zero coefficient.
+/** Returns the degree of the first non zero coefficient.
+ \param a sbasis function
+ \param tol largest abs val considered 0
+ \returns first non zero coefficient
+*/
 inline unsigned 
 valuation(SBasis const &a, double tol=0){
     unsigned val=0;
@@ -276,6 +286,12 @@ SBasis inverse(SBasis a, int k);
 //TODO: requires g(0)=0 & g(1)=1 atm. generalization should be obvious.
 SBasis compose_inverse(SBasis const &f, SBasis const &g, unsigned order=2, double tol=1e-3);
 
+/** Returns the sbasis on domain [0,1] that was t on [from, to]
+ \param a sbasis function
+ \param from,to interval
+ \returns sbasis
+
+*/
 inline SBasis portion(const SBasis &t, double from, double to) { return compose(t, Linear(from, to)); }
 
 // compute f(g)
@@ -296,7 +312,7 @@ inline std::ostream &operator<< (std::ostream &out_file, const SBasis & p) {
     return out_file;
 }
 
-// These are deprecated, use sbasis-math versions if possible
+// These are deprecated, use sbasis-math.h versions if possible
 SBasis sin(Linear bo, int k);
 SBasis cos(Linear bo, int k);
 
index 147aa9a5064cae21eb95e9b1b73e36676acba596..bec5e2d2c6ea8df57666fb2e797a7b2201cd8f8e 100644 (file)
@@ -1,3 +1,37 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
 #ifndef __2GEOM_SHAPE_H
 #define __2GEOM_SHAPE_H
 
index 13153c22cbae43568823ecfd037f8169f788fc97..4f3e8a13c5152699a871c858ac9b8dff1f09d560 100644 (file)
@@ -1,3 +1,37 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
 #ifndef _SOLVE_SBASIS_H
 #define _SOLVE_SBASIS_H
 #include <2geom/point.h>
index 5c42e6e1d1e57fecb3e88590b77a7850e20378b6..1d6d2d74d2f6dae23280feebee5bc69a0d6da355 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * Elliptical Arc - implementation of the svg elliptical arc path element
+/**
+ * \file
+ * \brief  Elliptical Arc - implementation of the SVGEllipticalArc path element
  *
  * Authors:
  *      MenTaLguY <mental@rydia.net>
@@ -66,20 +67,19 @@ class SVGEllipticalArc : public Curve
     {
     }
 
-    /*
-     * constructor
+    /**
+     * \brief constructor
      *
-     * input parameters:
-     * _initial_point:     initial arc end point;
-     * _rx:                ellipse x-axis ray length
-     * _ry:                ellipse y-axis ray length
-     * _rot_angle:         ellipse x-axis rotation angle;
-     * _large_arc:         if true the largest arc is chosen,
+     * \param _initial_point:     initial arc end point;
+     * \param _rx:                ellipse x-axis ray length
+     * \param _ry:                ellipse y-axis ray length
+     * \param _rot_angle:         ellipse x-axis rotation angle in radians;
+     * \param _large_arc:         if true the largest arc is chosen,
      *                     if false the smallest arc is chosen;
-     * _sweep :            if true the clockwise arc is chosen,
+     * \param _sweep :            if true the clockwise arc is chosen,
      *                     if false the counter-clockwise arc is chosen;
-     * _final_point:       final arc end point;
-     * _svg_compliant:     if true the class behaviour follows the Standard
+     * \param _final_point:       final arc end point;
+     * \param _svg_compliant:     if true the class behaviour follows the Standard
      *                     SVG 1.1 implementation guidelines (see Appendix F.6)
      *                     if false the class behavoiur is more strict
      *                     on input parameter
index bb452ec3336dcfc5e13d7ca7970a2af340a7949d..2f26870a5bf5e94f261f64544a46d23902a58408 100644 (file)
@@ -1,6 +1,7 @@
-#line 1 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
-/*
- * parse SVG path specifications
+#line 1 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
+/**
+ * \file
+ * \brief parse SVG path specifications
  *
  * Copyright 2007 MenTaLguY <mental@rydia.net>
  * Copyright 2007 Aaron Spike <aaron@ekips.org>
@@ -138,7 +139,7 @@ private:
 };
 
 
-#line 142 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.cpp"
+#line 143 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.cpp"
 static const char _svg_path_actions[] = {
        0, 1, 0, 1, 1, 1, 2, 1, 
        3, 1, 4, 1, 5, 1, 15, 1, 
@@ -1143,7 +1144,7 @@ static const int svg_path_first_final = 270;
 
 static const int svg_path_en_main = 1;
 
-#line 142 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 143 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
 
 
 void Parser::parse(char const *str)
@@ -1156,12 +1157,12 @@ throw(SVGPathParseError)
     _reset();
 
     
-#line 1160 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.cpp"
+#line 1161 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.cpp"
        {
        cs = svg_path_start;
        }
 
-#line 1165 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.cpp"
+#line 1166 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.cpp"
        {
        int _klen;
        unsigned int _trans;
@@ -1234,13 +1235,13 @@ _match:
                switch ( *_acts++ )
                {
        case 0:
-#line 154 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 155 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             start = p;
         }
        break;
        case 1:
-#line 158 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 159 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             char const *end=p;
             std::string buf(start, end);
@@ -1249,55 +1250,55 @@ _match:
         }
        break;
        case 2:
-#line 165 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 166 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             _push(1.0);
         }
        break;
        case 3:
-#line 169 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 170 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             _push(0.0);
         }
        break;
        case 4:
-#line 173 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 174 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             _absolute = true;
         }
        break;
        case 5:
-#line 177 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 178 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             _absolute = false;
         }
        break;
        case 6:
-#line 181 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 182 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             _moveTo(_pop_point());
         }
        break;
        case 7:
-#line 185 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 186 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             _lineTo(_pop_point());
         }
        break;
        case 8:
-#line 189 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 190 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             _hlineTo(Point(_pop_coord(X), _current[Y]));
         }
        break;
        case 9:
-#line 193 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 194 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             _vlineTo(Point(_current[X], _pop_coord(Y)));
         }
        break;
        case 10:
-#line 197 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 198 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             Point p = _pop_point();
             Point c1 = _pop_point();
@@ -1306,7 +1307,7 @@ _match:
         }
        break;
        case 11:
-#line 204 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 205 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             Point p = _pop_point();
             Point c1 = _pop_point();
@@ -1314,7 +1315,7 @@ _match:
         }
        break;
        case 12:
-#line 210 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 211 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             Point p = _pop_point();
             Point c = _pop_point();
@@ -1322,19 +1323,19 @@ _match:
         }
        break;
        case 13:
-#line 216 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 217 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             Point p = _pop_point();
             _quadTo(_quad_tangent, p);
         }
        break;
        case 14:
-#line 221 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 222 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             Point point = _pop_point();
             bool sweep = _pop_flag();
             bool large_arc = _pop_flag();
-            double angle = _pop();
+            double angle = deg_to_rad(_pop());
             double ry = _pop();
             double rx = _pop();
 
@@ -1342,16 +1343,16 @@ _match:
         }
        break;
        case 15:
-#line 232 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 233 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {
             _closePath();
         }
        break;
        case 16:
-#line 368 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 369 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
        {goto _out;}
        break;
-#line 1355 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.cpp"
+#line 1356 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.cpp"
                }
        }
 
@@ -1362,7 +1363,7 @@ _again:
        goto _resume;
        _out: {}
        }
-#line 378 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl"
+#line 379 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl"
 
 
     if ( cs < svg_path_first_final ) {
index 60d8a078b62b2375357c2dc555208cfeff34e4b5..12e80df5ad6e0456bec7e8ac301606b596ceba8f 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * parse SVG path specifications
+/**
+ * \file
+ * \brief  parse SVG path specifications
  *
  * Copyright 2007 MenTaLguY <mental@rydia.net>
  * Copyright 2007 Aaron Spike <aaron@ekips.org>
index 6da5afb7e37e15104dd8a226ffce23e19e1942e6..f2902750c89b14906cc050f3f196ec9b2e9b493c 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * callback interface for SVG path data
+/**
+ * \file
+ * \brief  callback interface for SVG path data
  *
  * Copyright 2007 MenTaLguY <mental@rydia.net>
  *
index 6500ccbc2c880ff3706cf1974a67b7b8ccd88a04..0214511ac328cdf85ec5370d95f7a46dbe7ca6ba 100644 (file)
@@ -1,3 +1,37 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
 #ifndef __2GEOM_SWEEP_H__
 #define __2GEOM_SWEEP_H__
 
index d21c5c617e9b1a18e8403d30552438c9d378859a..ac5a775c492975b485335f9a5284a175553c7d69 100644 (file)
@@ -1,3 +1,37 @@
+/**
+ * \file
+ * \brief  \todo brief description
+ *
+ * Authors:
+ *      ? <?@?.?>
+ * 
+ * Copyright ?-?  authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
 #ifndef SEEN_Geom_TRANSFORMS_H
 #define SEEN_Geom_TRANSFORMS_H
 
index ac99b8b007cc4ea2cca51dd8c294e9c8b2e1368a..5ab19174947a886f0f93776f503c137d8e9e0a8e 100644 (file)
@@ -1,7 +1,9 @@
 #ifndef LIB2GEOM_UTILS_HEADER
 #define LIB2GEOM_UTILS_HEADER
 
-/** Various utility functions.
+/**
+ * \file
+ * \brief  Various utility functions.
  *
  * Copyright 2007 Johan Engelen <goejendaagh@zonnet.nl>
  * Copyright 2006 Michael G. Sloan <mgsloan@gmail.com>
index 09d6ffe2416ed446576d5c0a2591c76192a1d432..0a367a1fed832d0837577935892dd86d443730ce 100644 (file)
@@ -401,7 +401,7 @@ void  Path::AddCurve(Geom::Curve const &c)
     else if(Geom::SVGEllipticalArc const *svg_elliptical_arc = dynamic_cast<Geom::SVGEllipticalArc const *>(&c)) {
         ArcTo( svg_elliptical_arc->finalPoint(),
                svg_elliptical_arc->ray(0), svg_elliptical_arc->ray(1),
-               svg_elliptical_arc->rotation_angle(),
+               svg_elliptical_arc->rotation_angle(),  /// \todo check that this parameter is in radians (rotation_angle returns the angle in radians!)
                svg_elliptical_arc->large_arc_flag(), !svg_elliptical_arc->sweep_flag() );
     } else { 
         //this case handles sbasis as well as all other curve types
index 03beb07348b1d1714cd36098cdb5880477f532b6..229ef65f70831f614fe0398827f683040e237d30 100644 (file)
@@ -36,6 +36,7 @@
 #include <cstring>
 #include <string>
 #include <locale.h>
+#include <stdlib.h>
 
 #include <popt.h>
 #ifndef POPT_TABLEEND
@@ -521,7 +522,12 @@ static int set_extensions_env()
 #endif
         tmp += oldenv;
     }
+#ifdef WIN32
+    /// \todo this does not work on windows, cannot find the setenv method or an equivalent.
+    //setenv("PYTHONPATH", tmp.c_str(), 1);
+#else
     setenv("PYTHONPATH", tmp.c_str(), 1);
+#endif
     
     return 0;
 }
index e999182c7e2114944f5b08734f5740235ce9b823..8b8289849dc3ca42d14aaf400e9dadee2b3579de 100644 (file)
@@ -437,15 +437,15 @@ void Preferences::addObserver(Observer &o)
     if (!node) return;
     
     // set additional data
-    _ObserverData *d = new _ObserverData;
-    d->_node = node;
-    d->_is_attr = !attr_key.empty();
-    o._data = static_cast<void*>(d);
+    _ObserverData *priv_data = new _ObserverData;
+    priv_data->_node = node;
+    priv_data->_is_attr = !attr_key.empty();
+    o._data = static_cast<void*>(priv_data);
     
     _observer_map[&o] = new PrefNodeObserver(o, attr_key);
     
     // if we watch a single pref, we want to receive notifications only for a single node
-    if (d->_is_attr) {
+    if (priv_data->_is_attr) {
         node->addObserver( *(_observer_map[&o]) );
     } else {
         node->addSubtreeObserver( *(_observer_map[&o]) );
@@ -457,10 +457,15 @@ void Preferences::removeObserver(Observer &o)
     // prevent removing an observer which was not added
     if ( _observer_map.find(&o) == _observer_map.end() ) return;
     Inkscape::XML::Node *node = static_cast<_ObserverData*>(o._data)->_node;
-    delete static_cast<_ObserverData*>(o._data);
+    _ObserverData *priv_data = static_cast<_ObserverData*>(o._data);
     o._data = NULL;
     
-    node->removeSubtreeObserver( *(_observer_map[&o]) );
+    if (priv_data->_is_attr)
+        node->removeObserver( *(_observer_map[&o]) );
+    else
+        node->removeSubtreeObserver( *(_observer_map[&o]) );
+
+    delete priv_data;
     delete _observer_map[&o];
     _observer_map.erase(&o);
 }
index d09d43b9da0f282cf82b9194c5984a645068867b..01389a3d0e41e910926ff47ff3fb1b39ccb5125d 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/**
  * Inkscape::SVG::PathString - builder for SVG path strings
  *
  * Copyright 2007 MenTaLguY <mental@rydia.net>
@@ -113,6 +113,9 @@ public:
         return *this;
     }
 
+    /**
+     *  \param rot the angle in degrees
+     */
     PathString &arcTo(NR::Coord rx, NR::Coord ry, NR::Coord rot,
                       bool large_arc, bool sweep,
                       NR::Point p)
index 334ba0c1a005c6ab67d6dbe4f3c0dce4820900e0..88e340bd487c2c4528222afb556c1e7b6dc66715 100644 (file)
@@ -46,6 +46,7 @@
 #include <2geom/svg-path.h>
 #include <2geom/svg-path-parser.h>
 #include <2geom/exception.h>
+#include <2geom/angle.h>
 
 /*
  * Parses the path in str. When an error is found in the pathstring, this method
@@ -92,7 +93,7 @@ static void sp_svg_write_curve(Inkscape::SVG::PathString & str, Geom::Curve cons
     }
     else if(Geom::SVGEllipticalArc const *svg_elliptical_arc = dynamic_cast<Geom::SVGEllipticalArc const *>(c)) {
         str.arcTo( svg_elliptical_arc->ray(0), svg_elliptical_arc->ray(1),
-                   svg_elliptical_arc->rotation_angle(),
+                   Geom::rad_to_deg(svg_elliptical_arc->rotation_angle()),
                    svg_elliptical_arc->large_arc_flag(), svg_elliptical_arc->sweep_flag(),
                    svg_elliptical_arc->finalPoint() );
     }