From 01d27eab5fca2dcb8e883011f8be77ae6b78a11c Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 27 Oct 2008 23:45:31 -0500 Subject: [PATCH] Merge from trunk --- po/de.po | 2 +- src/2geom/basic-intersection.cpp | 80 +++++++ src/2geom/basic-intersection.h | 49 +++++ src/2geom/bezier-curve.h | 5 +- src/2geom/bezier-to-sbasis.h | 5 +- src/2geom/bezier-utils.h | 11 +- src/2geom/bezier.h | 5 +- src/2geom/choose.h | 5 +- src/2geom/circle.h | 5 +- src/2geom/circulator.h | 5 +- src/2geom/concepts.h | 5 +- src/2geom/conjugate_gradient.h | 5 +- src/2geom/convex-cover.h | 5 +- src/2geom/coord.h | 5 +- src/2geom/crossing.h | 34 +++ src/2geom/curve.h | 5 +- src/2geom/curves.h | 5 +- src/2geom/d2-sbasis.h | 38 ++++ src/2geom/d2.h | 26 ++- src/2geom/ellipse.h | 5 +- src/2geom/elliptical-arc.h | 5 +- src/2geom/exception.h | 4 +- src/2geom/forward.h | 5 +- src/2geom/geom.cpp | 5 +- src/2geom/geom.h | 9 +- src/2geom/hvlinesegment.h | 5 +- src/2geom/interval.h | 5 +- src/2geom/isnan.h | 34 +++ src/2geom/linear.h | 5 +- src/2geom/matrix.h | 2 +- src/2geom/nearest-point.h | 6 +- src/2geom/ord.h | 33 +++ src/2geom/path-intersection.cpp | 36 ++-- src/2geom/path-intersection.h | 34 +++ src/2geom/path.h | 10 +- src/2geom/pathvector.h | 5 +- src/2geom/piecewise.h | 28 ++- src/2geom/point.cpp | 34 +-- src/2geom/point.h | 7 +- src/2geom/poly.h | 34 +++ src/2geom/quadtree.h | 34 +++ src/2geom/rect.h | 86 ++++---- src/2geom/region.h | 34 +++ src/2geom/sbasis-2d.cpp | 117 ++++++++++ src/2geom/sbasis-2d.h | 50 ++++- src/2geom/sbasis-curve.h | 5 +- src/2geom/sbasis-geometric.cpp | 355 ++++++++++++++++++++++++++++++- src/2geom/sbasis-geometric.h | 28 ++- src/2geom/sbasis-math.cpp | 62 ++++++ src/2geom/sbasis-math.h | 5 +- src/2geom/sbasis-poly.cpp | 12 ++ src/2geom/sbasis-poly.h | 34 ++- src/2geom/sbasis-roots.cpp | 96 ++++----- src/2geom/sbasis-to-bezier.cpp | 202 +++++------------- src/2geom/sbasis-to-bezier.h | 34 +++ src/2geom/sbasis.cpp | 169 ++++++++++++--- src/2geom/sbasis.h | 24 ++- src/2geom/shape.h | 34 +++ src/2geom/solver.h | 34 +++ src/2geom/svg-elliptical-arc.h | 26 +-- src/2geom/svg-path-parser.cpp | 55 ++--- src/2geom/svg-path-parser.h | 5 +- src/2geom/svg-path.h | 5 +- src/2geom/sweep.h | 34 +++ src/2geom/transforms.h | 34 +++ src/2geom/utils.h | 4 +- src/livarot/PathCutting.cpp | 2 +- src/main.cpp | 6 + src/preferences.cpp | 19 +- src/svg/path-string.h | 5 +- src/svg/svg-path.cpp | 3 +- 71 files changed, 1788 insertions(+), 436 deletions(-) diff --git a/po/de.po b/po/de.po index 6ebe9269e..17d2fccda 100644 --- 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" diff --git a/src/2geom/basic-intersection.cpp b/src/2geom/basic-intersection.cpp index 334c23fea..2a40e7f45 100644 --- a/src/2geom/basic-intersection.cpp +++ b/src/2geom/basic-intersection.cpp @@ -517,6 +517,86 @@ std::vector > 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& A, D2 const& B, + double m_precision, + double *a_t, double* b_t) { + std::vector< std::pair > xs; + std::vector 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& A, D2 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; +} }; /* diff --git a/src/2geom/basic-intersection.h b/src/2geom/basic-intersection.h index a7750e015..77374b5ff 100644 --- a/src/2geom/basic-intersection.h +++ b/src/2geom/basic-intersection.h @@ -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 >& xs, std::vector const& B, double precision = 1e-5); +/** + * Compute the Hausdorf distance from A to B only. + */ +double hausdorfl(D2& A, D2 const& B, + double m_precision, + double *a_t=0, double* b_t=0); +/** + * Compute the symmetric Hausdorf distance. + */ +double hausdorf(D2& A, D2 const& B, + double m_precision, + double *a_t=0, double* b_t=0); } +#endif // !SEEN_GEOM_BASICINTERSECTION_H + /* Local Variables: mode:c++ diff --git a/src/2geom/bezier-curve.h b/src/2geom/bezier-curve.h index 45d0b61f3..135aa4f71 100644 --- a/src/2geom/bezier-curve.h +++ b/src/2geom/bezier-curve.h @@ -1,5 +1,6 @@ -/* - * Bezier-Curve +/** + * \file + * \brief Bezier-Curve * * Authors: * MenTaLguY diff --git a/src/2geom/bezier-to-sbasis.h b/src/2geom/bezier-to-sbasis.h index d5279a570..71e39e2c7 100644 --- a/src/2geom/bezier-to-sbasis.h +++ b/src/2geom/bezier-to-sbasis.h @@ -1,5 +1,6 @@ -/* - * bezier-to-sbasis.h +/** + * \file bezier-to-sbasis.h + * \brief \todo brief description * * Copyright 2006 Nathan Hurst * diff --git a/src/2geom/bezier-utils.h b/src/2geom/bezier-utils.h index 68ae8c0e7..3d79df3b2 100644 --- a/src/2geom/bezier-utils.h +++ b/src/2geom/bezier-utils.h @@ -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: diff --git a/src/2geom/bezier.h b/src/2geom/bezier.h index 6e11ad58b..94dd909ca 100644 --- a/src/2geom/bezier.h +++ b/src/2geom/bezier.h @@ -1,5 +1,6 @@ -/* - * bezier.h +/** + * \file bezier.h + * \brief \todo brief description * * Copyright 2007 MenTaLguY * Copyright 2007 Michael Sloan diff --git a/src/2geom/choose.h b/src/2geom/choose.h index 141a23f37..337569e36 100644 --- a/src/2geom/choose.h +++ b/src/2geom/choose.h @@ -1,5 +1,6 @@ -/* - * choose.h +/** + * \file choose.h + * \brief \todo brief description * * Copyright 2006 Nathan Hurst * diff --git a/src/2geom/circle.h b/src/2geom/circle.h index 2f81e27bc..1f9871276 100644 --- a/src/2geom/circle.h +++ b/src/2geom/circle.h @@ -1,5 +1,6 @@ -/* - * Circle Curve +/** + * \file + * \brief Circle Curve * * Authors: * Marco Cecchetti diff --git a/src/2geom/circulator.h b/src/2geom/circulator.h index 65d337e82..57f3bf741 100644 --- a/src/2geom/circulator.h +++ b/src/2geom/circulator.h @@ -1,5 +1,6 @@ -/* - * ciculator.h +/** + * \file circulator.h + * \brief \todo brief description * * Copyright 2006 MenTaLguY * diff --git a/src/2geom/concepts.h b/src/2geom/concepts.h index 6f10c8bb0..8f4d98ef2 100644 --- a/src/2geom/concepts.h +++ b/src/2geom/concepts.h @@ -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 * diff --git a/src/2geom/conjugate_gradient.h b/src/2geom/conjugate_gradient.h index 2d6050fd3..6f4098b5b 100644 --- a/src/2geom/conjugate_gradient.h +++ b/src/2geom/conjugate_gradient.h @@ -1,5 +1,6 @@ -/* - * conjugate_gradient.h +/** + * \file + * \brief \todo brief description * * Copyright 2006 Nathan Hurst * diff --git a/src/2geom/convex-cover.h b/src/2geom/convex-cover.h index 29f522e91..f22177746 100644 --- a/src/2geom/convex-cover.h +++ b/src/2geom/convex-cover.h @@ -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 * Copyright 2006 Michael G. Sloan diff --git a/src/2geom/coord.h b/src/2geom/coord.h index 99e249e29..b44a0f71e 100644 --- a/src/2geom/coord.h +++ b/src/2geom/coord.h @@ -1,5 +1,6 @@ -/* - * coord.h +/** + * \file + * \brief Defines the Coord "real" type with sufficient precision for coordinates. * * Copyright 2006 Nathan Hurst * diff --git a/src/2geom/crossing.h b/src/2geom/crossing.h index b16c7e46d..291f69382 100644 --- a/src/2geom/crossing.h +++ b/src/2geom/crossing.h @@ -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 diff --git a/src/2geom/curve.h b/src/2geom/curve.h index 6ab05b750..b81548ba8 100644 --- a/src/2geom/curve.h +++ b/src/2geom/curve.h @@ -1,5 +1,6 @@ -/* - * Abstract Curve Type +/** + * \file + * \brief Abstract Curve Type * * Authors: * MenTaLguY diff --git a/src/2geom/curves.h b/src/2geom/curves.h index b0b16df3d..f45d1e31f 100644 --- a/src/2geom/curves.h +++ b/src/2geom/curves.h @@ -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 diff --git a/src/2geom/d2-sbasis.h b/src/2geom/d2-sbasis.h index 91ceb31c9..dd1a8e11c 100644 --- a/src/2geom/d2-sbasis.h +++ b/src/2geom/d2-sbasis.h @@ -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. */ diff --git a/src/2geom/d2.h b/src/2geom/d2.h index 731a084a1..7e2bbae53 100644 --- a/src/2geom/d2.h +++ b/src/2geom/d2.h @@ -1,5 +1,6 @@ -/* - * d2.h - Lifts one dimensional objects into 2d +/** + * \file + * \brief Lifts one dimensional objects into 2d * * Copyright 2007 Michael Sloan * @@ -39,7 +40,13 @@ #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 is a Point. A D2 is a standard axis aligned rectangle. + * D2 provides a 2d parametric function which maps t to a point + * x(t), y(t) + */ template class D2{ //BOOST_CLASS_REQUIRE(T, boost, AssignableConcept); @@ -247,6 +254,19 @@ D2 operator*(D2 const &v, Matrix const &m) { return ret; } +//IMPL: MultiplicableConcept +template +inline D2 +operator*(D2 const & a, T const & b) { + boost::function_requires >(); + D2 ret; + for(unsigned i = 0; i < 2; i++) + ret[i] = a[i] * b; + return ret; +} + +//IMPL: + //IMPL: OffsetableConcept template inline D2 diff --git a/src/2geom/ellipse.h b/src/2geom/ellipse.h index 1f0dfce63..d5b882bc4 100644 --- a/src/2geom/ellipse.h +++ b/src/2geom/ellipse.h @@ -1,5 +1,6 @@ -/* - * Ellipse Curve +/** + * \file + * \brief Ellipse Curve * * Authors: * Marco Cecchetti diff --git a/src/2geom/elliptical-arc.h b/src/2geom/elliptical-arc.h index 46b94c0df..24b4fcf46 100644 --- a/src/2geom/elliptical-arc.h +++ b/src/2geom/elliptical-arc.h @@ -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 diff --git a/src/2geom/exception.h b/src/2geom/exception.h index 6151f7a57..99db54b45 100644 --- a/src/2geom/exception.h +++ b/src/2geom/exception.h @@ -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 * diff --git a/src/2geom/forward.h b/src/2geom/forward.h index d4ac1af1e..184801ef4 100644 --- a/src/2geom/forward.h +++ b/src/2geom/forward.h @@ -1,5 +1,6 @@ -/* - * forward - this file contains forward declarations of 2geom types +/** + * \file + * \brief Contains forward declarations of 2geom types * * Authors: * Johan Engelen diff --git a/src/2geom/geom.cpp b/src/2geom/geom.cpp index ded1a1940..d0689981a 100644 --- a/src/2geom/geom.cpp +++ b/src/2geom/geom.cpp @@ -1,5 +1,6 @@ -/** @file - * @brief Various geometrical calculations. +/** + * \file geom.cpp + * \brief Various geometrical calculations. */ #ifdef HAVE_CONFIG_H diff --git a/src/2geom/geom.h b/src/2geom/geom.h index 210d236a1..aeb40f7e1 100644 --- a/src/2geom/geom.h +++ b/src/2geom/geom.h @@ -1,7 +1,8 @@ -/** @file - * @brief Various geometrical calculations - */ -/* Authors: +/** + * \file + * \brief Various geometrical calculations + * + * Authors: * Nathan Hurst * * Copyright (C) 1999-2002 authors diff --git a/src/2geom/hvlinesegment.h b/src/2geom/hvlinesegment.h index 66de31d70..3e1287682 100644 --- a/src/2geom/hvlinesegment.h +++ b/src/2geom/hvlinesegment.h @@ -1,5 +1,6 @@ -/* - * Horizontal and Vertical Line Segment +/** + * \file + * \brief Horizontal and Vertical Line Segment * * Copyright 2008 Marco Cecchetti * diff --git a/src/2geom/interval.h b/src/2geom/interval.h index 2d9f4abd8..8f7a0b2a1 100644 --- a/src/2geom/interval.h +++ b/src/2geom/interval.h @@ -1,5 +1,6 @@ -/* - * interval.h - Simple closed interval class +/** + * \file + * \brief Simple closed interval class * * Copyright 2007 Michael Sloan * diff --git a/src/2geom/isnan.h b/src/2geom/isnan.h index 6b94daa6e..b4e7341ff 100644 --- a/src/2geom/isnan.h +++ b/src/2geom/isnan.h @@ -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__ diff --git a/src/2geom/linear.h b/src/2geom/linear.h index bc7af564c..4594e17be 100644 --- a/src/2geom/linear.h +++ b/src/2geom/linear.h @@ -1,5 +1,6 @@ -/* - * linear.h - Linear fragment function class +/** + * \file + * \brief Linear fragment function class * * Authors: * Nathan Hurst diff --git a/src/2geom/matrix.h b/src/2geom/matrix.h index c81efab68..e207bf812 100644 --- a/src/2geom/matrix.h +++ b/src/2geom/matrix.h @@ -2,7 +2,7 @@ #define __Geom_MATRIX_H__ /** \file - * Definition of Geom::Matrix types. + * \brief Definition of Geom::Matrix types. * * Main authors: * Lauris Kaplinski : diff --git a/src/2geom/nearest-point.h b/src/2geom/nearest-point.h index 0ca28c4f2..19485242c 100644 --- a/src/2geom/nearest-point.h +++ b/src/2geom/nearest-point.h @@ -1,6 +1,6 @@ -/* - * nearest point routines for D2 and Piecewise> - * +/** + * \file + * \brief nearest point routines for D2 and Piecewise> * * Authors: * diff --git a/src/2geom/ord.h b/src/2geom/ord.h index ec5bc650c..8c011529a 100644 --- a/src/2geom/ord.h +++ b/src/2geom/ord.h @@ -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__ diff --git a/src/2geom/path-intersection.cpp b/src/2geom/path-intersection.cpp index 2612aa125..715c67c23 100644 --- a/src/2geom/path-intersection.cpp +++ b/src/2geom/path-intersection.cpp @@ -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 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 curve_mono_splits(Curve const &d) { std::vector rs = d.roots(0, X); append(rs, d.roots(0, Y)); @@ -354,7 +360,7 @@ std::vector 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 offset_doubles(std::vector const &x, double offs) { std::vector ret; for(unsigned i = 0; i < x.size(); i++) { @@ -363,7 +369,8 @@ std::vector offset_doubles(std::vector 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 path_mono_splits(Path const &p) { @@ -394,7 +401,8 @@ std::vector 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 > paths_mono_splits(std::vector const &ps) { @@ -404,7 +412,8 @@ std::vector > paths_mono_splits(std::vector 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 > split_bounds(std::vector 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. diff --git a/src/2geom/path-intersection.h b/src/2geom/path-intersection.h index 73dc3da8b..4eef16823 100644 --- a/src/2geom/path-intersection.h +++ b/src/2geom/path-intersection.h @@ -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 diff --git a/src/2geom/path.h b/src/2geom/path.h index 1b59ea011..e02b749e7 100644 --- a/src/2geom/path.h +++ b/src/2geom/path.h @@ -1,5 +1,6 @@ -/* - * Path - Series of continuous curves +/** + * \file + * \brief Path - Series of continuous curves * * Authors: * MenTaLguY @@ -564,6 +565,11 @@ public: } } + + /* + * It is important to note that the coordinates passed to appendNew should be finite! + */ + template void appendNew(A a) { unshare(); diff --git a/src/2geom/pathvector.h b/src/2geom/pathvector.h index cdc774c55..5df3ad00c 100644 --- a/src/2geom/pathvector.h +++ b/src/2geom/pathvector.h @@ -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. * diff --git a/src/2geom/piecewise.h b/src/2geom/piecewise.h index d25c04bc4..ec3ba26ce 100644 --- a/src/2geom/piecewise.h +++ b/src/2geom/piecewise.h @@ -1,5 +1,6 @@ -/* - * piecewise.h - Piecewise function class +/** + * \file + * \brief Piecewise function class * * Copyright 2007 Michael Sloan * @@ -40,7 +41,28 @@ #include 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 class Piecewise { BOOST_CLASS_REQUIRE(T, Geom, FragmentConcept); diff --git a/src/2geom/point.cpp b/src/2geom/point.cpp index 42a7ecef3..5dd7b52f2 100644 --- a/src/2geom/point.cpp +++ b/src/2geom/point.cpp @@ -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; + } } - } } } diff --git a/src/2geom/point.h b/src/2geom/point.h index 2cab3d7fe..e6e74242d 100644 --- a/src/2geom/point.h +++ b/src/2geom/point.h @@ -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 @@ -16,7 +17,7 @@ enum Dim2 { X=0, Y=1 }; class Matrix; -/// Cartesian point. +/// Cartesian 2D point. class Point { Coord _pt[2]; diff --git a/src/2geom/poly.h b/src/2geom/poly.h index 152626698..86041a889 100644 --- a/src/2geom/poly.h +++ b/src/2geom/poly.h @@ -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 diff --git a/src/2geom/quadtree.h b/src/2geom/quadtree.h index 0770cd5f8..5338698cf 100644 --- a/src/2geom/quadtree.h +++ b/src/2geom/quadtree.h @@ -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 #include diff --git a/src/2geom/rect.h b/src/2geom/rect.h index ee1b0d764..563c8a058 100644 --- a/src/2geom/rect.h +++ b/src/2geom/rect.h @@ -1,6 +1,8 @@ +/** + * \file + * \brief D2 specialization to Rect + */ /* - * rect.h - D2 specialization to Rect - * * Copyright 2007 Michael Sloan * * This library is free software; you can redistribute it and/or @@ -44,11 +46,15 @@ #include namespace Geom { - +/** D2 specialization to Rect */ typedef D2 Rect; Rect unify(const Rect &, const Rect &); - +/** + * %Rect class. + * The Rect class is actually a specialisation of D2. + * + */ template<> class D2 { private: @@ -74,7 +80,7 @@ class D2 { 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 { 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 unify(boost::optional const & a, boost::optional const & b) { if (!a) { return b; @@ -169,30 +180,33 @@ inline boost::optional 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)); } diff --git a/src/2geom/region.h b/src/2geom/region.h index 960a570a4..7b2f5763d 100644 --- a/src/2geom/region.h +++ b/src/2geom/region.h @@ -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 diff --git a/src/2geom/sbasis-2d.cpp b/src/2geom/sbasis-2d.cpp index 79e99519a..9566e0a19 100644 --- a/src/2geom/sbasis-2d.cpp +++ b/src/2geom/sbasis-2d.cpp @@ -1,4 +1,5 @@ #include <2geom/sbasis-2d.h> +#include <2geom/sbasis-geometric.h> namespace Geom{ @@ -69,6 +70,122 @@ compose_each(D2 const &fg, D2 const &p) { return D2(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. + * 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 +sb2dsolve(SBasis2d const &f, Geom::Point const &A, Geom::Point const &B, unsigned degmax){ + D2result(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. + * 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 +sb2d_cubic_solve(SBasis2d const &f, Geom::Point const &A, Geom::Point const &B){ + D2result;//(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 > candidates = cubics_fitting_curvature(A,B,V0,V1,D2fVV0,D2fVV1); + if (candidates.size()==0) { + return D2(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; ifabs(bounds.min()) ? fabs(bounds.max()) : fabs(bounds.min()) ); + if ( new_error < error || error < 0 ){ + error = new_error; + best = i; + } + } + return candidates[best]; +} + + + + }; /* diff --git a/src/2geom/sbasis-2d.h b/src/2geom/sbasis-2d.h index 1845b5c99..c29d53bcb 100644 --- a/src/2geom/sbasis-2d.h +++ b/src/2geom/sbasis-2d.h @@ -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 @@ -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 +sb2dsolve(SBasis2d const &f, Geom::Point const &A, Geom::Point const &B, unsigned degmax=2); + +D2 +sb2d_cubic_solve(SBasis2d const &f, Geom::Point const &A, Geom::Point const &B); + }; /* diff --git a/src/2geom/sbasis-curve.h b/src/2geom/sbasis-curve.h index 6b3888594..e11919401 100644 --- a/src/2geom/sbasis-curve.h +++ b/src/2geom/sbasis-curve.h @@ -1,5 +1,6 @@ -/* - * Simmetric Power Bais Curve +/** + * \file + * \brief Symmetric Power Basis Curve * * Authors: * MenTaLguY diff --git a/src/2geom/sbasis-geometric.cpp b/src/2geom/sbasis-geometric.cpp index 887ca9995..f0170ec6b 100644 --- a/src/2geom/sbasis-geometric.cpp +++ b/src/2geom/sbasis-geometric.cpp @@ -127,6 +127,12 @@ Geom::cutAtRoots(Piecewise > 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 Geom::atan2(Piecewise > const &vect, double tol, unsigned order){ Piecewise result; @@ -152,24 +158,47 @@ Geom::atan2(Piecewise > 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 Geom::atan2(D2 const &vect, double tol, unsigned order){ return atan2(Piecewise >(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 > Geom::tan2(SBasis const &angle, double tol, unsigned order){ return tan2(Piecewise(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 > Geom::tan2(Piecewise const &angle, double tol, unsigned order){ return D2 >(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 > 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 > Geom::unitVector(D2 const &V_in, double tol, unsigned order){ D2 V = RescaleForNonVanishingEnds(V_in); @@ -234,6 +263,14 @@ Geom::unitVector(D2 const &V_in, double tol, unsigned order){ } } +/** Return a Piecewise > 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 > Geom::unitVector(Piecewise > const &V, double tol, unsigned order){ Piecewise > result; @@ -248,6 +285,11 @@ Geom::unitVector(Piecewise > 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 Geom::arcLengthSb(Piecewise > const &M, double tol){ Piecewise > dM = derivative(M); @@ -256,11 +298,18 @@ Geom::arcLengthSb(Piecewise > 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 Geom::arcLengthSb(D2 const &M, double tol){ return arcLengthSb(Piecewise >(M), tol); } +#if 0 double Geom::length(D2 const &M, double tol){ @@ -273,9 +322,15 @@ Geom::length(Piecewise > const &M, Piecewise 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 Geom::curvature(D2 const &M, double tol) { D2 dM=derivative(M); @@ -287,6 +342,13 @@ Geom::curvature(D2 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 Geom::curvature(Piecewise > const &V, double tol){ Piecewise result; @@ -303,6 +365,12 @@ Geom::curvature(Piecewise > 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 > Geom::arc_length_parametrization(D2 const &M, unsigned order, @@ -326,6 +394,12 @@ Geom::arc_length_parametrization(D2 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 > Geom::arc_length_parametrization(Piecewise > const &M, unsigned order, @@ -338,17 +412,83 @@ Geom::arc_length_parametrization(Piecewise > 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 +static double sb_length_integrating(double t, void* param) { + SBasis* pc = (SBasis*)param; + return sqrt((*pc)(t)); +} + +/** Calculates the length of a D2 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 const &B, double &result, double &abs_error, double tol) { + D2 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 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 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 > 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 > 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 > const &p, Point& centroid, double &area) { Point centroid_tmp(0,0); double atmp = 0; @@ -374,6 +514,203 @@ unsigned Geom::centroid(Piecewise > 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 +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(); + p = compose(p,Linear(domain.min(),domain.max())); + std::vectorrts = roots(p); + for (unsigned i=0; i > +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 > 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 lambda0,lambda1; + double dM1xdM0=cross(dM1,dM0); + if (fabs(dM1xdM0) solns=solve_poly(a,4); + vector solns=solve_lambda0(a0,a1,c0,c1,insist_on_speed_signs); + for (unsigned i=0;i=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 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 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 > +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 > +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 diff --git a/src/2geom/sbasis-geometric.h b/src/2geom/sbasis-geometric.h index 7e067d801..18c666b11 100644 --- a/src/2geom/sbasis-geometric.h +++ b/src/2geom/sbasis-geometric.h @@ -4,7 +4,10 @@ #include <2geom/piecewise.h> #include -/** two-dimensional geometric operators. +/** + * \file + * \brief two-dimensional geometric operators. + * * Copyright 2007, JFBarraud * Copyright 2007, njh * @@ -61,6 +64,8 @@ Piecewise arcLengthSb(Piecewise > const &M, double tol=.01); double length( D2 const &M, double tol=.01); double length(Piecewise > const &M, double tol=.01); +void length_integrating(D2 const &B, double &result, double &abs_error, double tol); + Piecewise > arc_length_parametrization(D2 const &M, unsigned order=3, @@ -73,6 +78,27 @@ arc_length_parametrization(Piecewise > const &M, unsigned centroid(Piecewise > const &p, Point& centroid, double &area); +std::vector > +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 > +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 > +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 diff --git a/src/2geom/sbasis-math.cpp b/src/2geom/sbasis-math.cpp index f5a8ab7a1..1d179a563 100644 --- a/src/2geom/sbasis-math.cpp +++ b/src/2geom/sbasis-math.cpp @@ -45,9 +45,15 @@ namespace Geom { #include //-|x|----------------------------------------------------------------------- +/** Return the absolute value of a function pointwise. + \param f function +*/ Piecewise abs(SBasis const &f){ return abs(Piecewise(f)); } +/** Return the absolute value of a function pointwise. + \param f function +*/ Piecewise abs(Piecewise const &f){ Piecewise absf=partition(f,roots(f)); for (unsigned i=0; i abs(Piecewise const &f){ } //-max(x,y), min(x,y)-------------------------------------------------------- +/** Return the greater of the two functions pointwise. + \param f, g two functions +*/ Piecewise max( SBasis const &f, SBasis const &g){ return max(Piecewise(f),Piecewise(g)); } +/** Return the greater of the two functions pointwise. + \param f, g two functions +*/ Piecewise max(Piecewise const &f, SBasis const &g){ return max(f,Piecewise(g)); } +/** Return the greater of the two functions pointwise. + \param f, g two functions +*/ Piecewise max( SBasis const &f, Piecewise const &g){ return max(Piecewise(f),g); } +/** Return the greater of the two functions pointwise. + \param f, g two functions +*/ Piecewise max(Piecewise const &f, Piecewise const &g){ Piecewise max=partition(f,roots(f-g)); Piecewise gg =partition(g,max.cuts); @@ -76,20 +94,38 @@ Piecewise max(Piecewise const &f, Piecewise const &g){ return max; } +/** Return the more negative of the two functions pointwise. + \param f, g two functions +*/ Piecewise 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 min(Piecewise const &f, SBasis const &g){ return -max(-f,-g); } +/** Return the more negative of the two functions pointwise. + \param f, g two functions +*/ Piecewise min( SBasis const &f, Piecewise const &g){ return -max(-f,-g); } +/** Return the more negative of the two functions pointwise. + \param f, g two functions +*/ Piecewise min(Piecewise const &f, Piecewise const &g){ return -max(-f,-g); } //-sign(x)--------------------------------------------------------------- +/** Return the sign of the two functions pointwise. + \param f function +*/ Piecewise signSb(SBasis const &f){ return signSb(Piecewise(f)); } +/** Return the sign of the two functions pointwise. + \param f function +*/ Piecewise signSb(Piecewise const &f){ Piecewise sign=partition(f,roots(f)); for (unsigned i=0; i sqrt_internal(SBasis const &f, return sqrtf0; } +/** Compute the sqrt of a function. + \param f function +*/ Piecewise 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 sqrt(Piecewise const &f, double tol, int order){ Piecewise result; Piecewise zero = Piecewise(Linear(tol*tol)); @@ -159,9 +201,24 @@ Piecewise sqrt(Piecewise 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 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 sin(Piecewise 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 cos(Piecewise const &f, double tol, int order){ Piecewise result; for (unsigned i=0; i cos(Piecewise 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 cos( SBasis const &f, double tol, int order){ double alpha = (f.at0()+f.at1())/2.; SBasis x = f-alpha; diff --git a/src/2geom/sbasis-math.h b/src/2geom/sbasis-math.h index 2a51bffb3..053c2d285 100644 --- a/src/2geom/sbasis-math.h +++ b/src/2geom/sbasis-math.h @@ -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 diff --git a/src/2geom/sbasis-poly.cpp b/src/2geom/sbasis-poly.cpp index 3fee0afe4..ec632d5a2 100644 --- a/src/2geom/sbasis-poly.cpp +++ b/src/2geom/sbasis-poly.cpp @@ -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(); diff --git a/src/2geom/sbasis-poly.h b/src/2geom/sbasis-poly.h index 09c8e5487..1c509cf84 100644 --- a/src/2geom/sbasis-poly.h +++ b/src/2geom/sbasis-poly.h @@ -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{ diff --git a/src/2geom/sbasis-roots.cpp b/src/2geom/sbasis-roots.cpp index 09a84050b..2eb1e4cbb 100644 --- a/src/2geom/sbasis-roots.cpp +++ b/src/2geom/sbasis-roots.cpp @@ -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 > multi_roots(SBasis const &f, std::vector const &levels, double htol, @@ -262,57 +302,6 @@ std::vector > 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 & roots, @@ -343,6 +332,11 @@ std::vector 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 roots(SBasis const & s) { switch(s.size()) { case 0: diff --git a/src/2geom/sbasis-to-bezier.cpp b/src/2geom/sbasis-to-bezier.cpp index 27e3047fd..dfb24f9d9 100644 --- a/src/2geom/sbasis-to-bezier.cpp +++ b/src/2geom/sbasis-to-bezier.cpp @@ -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 & bz, D2 const& sb, size_t sz) { Bezier bzx, bzy; @@ -160,11 +174,16 @@ void sbasis_to_bezier (std::vector & bz, D2 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 & sb, std::vector const& bz) { size_t n = bz.size() - 1; @@ -252,138 +279,8 @@ void bezier_to_sbasis (D2 & sb, std::vector 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(n-2*k-1, j-k) / - choose(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 -sbasis_to_bezier(D2 const &B, unsigned qq) { - std::vector 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 -D2 > sbasis_to_bezier(D2 const &B) { - return D2 >(sbasis_to_bezier(B[0]), sbasis_to_bezier(B[1])); -} -*/ -#endif - -#if 0 // using old path -//std::vector -// mutating -void -subpath_from_sbasis(Geom::OldPathSetBuilder &pb, D2 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 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 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 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 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 const &B, double tol, bool only_cubicbeziers) { PathBuilder pb; @@ -464,10 +369,13 @@ path_from_sbasis(D2 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 path_from_piecewise(Geom::Piecewise > const &B, double tol, bool only_cubicbeziers) { Geom::PathBuilder pb; diff --git a/src/2geom/sbasis-to-bezier.h b/src/2geom/sbasis-to-bezier.h index c9d5cbbbc..2875ab3f0 100644 --- a/src/2geom/sbasis-to-bezier.h +++ b/src/2geom/sbasis-to-bezier.h @@ -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 diff --git a/src/2geom/sbasis.cpp b/src/2geom/sbasis.cpp index a7e049def..2619da594 100644 --- a/src/2geom/sbasis.cpp +++ b/src/2geom/sbasis.cpp @@ -38,28 +38,17 @@ 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 SBasis::valueAndDerivatives(double t, unsigned n) const { - std::vector ret(n+1); - ret[0]=valueAt(t); + std::vector 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 diff --git a/src/2geom/sbasis.h b/src/2geom/sbasis.h index a9939f92a..72bf422e7 100644 --- a/src/2geom/sbasis.h +++ b/src/2geom/sbasis.h @@ -1,5 +1,6 @@ -/* - * sbasis.h - S-power basis function class +/** + * \file + * \brief Defines S-power basis function class * * Authors: * Nathan Hurst @@ -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); diff --git a/src/2geom/shape.h b/src/2geom/shape.h index 147aa9a50..bec5e2d2c 100644 --- a/src/2geom/shape.h +++ b/src/2geom/shape.h @@ -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 diff --git a/src/2geom/solver.h b/src/2geom/solver.h index 13153c22c..4f3e8a13c 100644 --- a/src/2geom/solver.h +++ b/src/2geom/solver.h @@ -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> diff --git a/src/2geom/svg-elliptical-arc.h b/src/2geom/svg-elliptical-arc.h index 5c42e6e1d..1d6d2d74d 100644 --- a/src/2geom/svg-elliptical-arc.h +++ b/src/2geom/svg-elliptical-arc.h @@ -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 @@ -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 diff --git a/src/2geom/svg-path-parser.cpp b/src/2geom/svg-path-parser.cpp index bb452ec33..2f26870a5 100644 --- a/src/2geom/svg-path-parser.cpp +++ b/src/2geom/svg-path-parser.cpp @@ -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 * Copyright 2007 Aaron Spike @@ -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 ) { diff --git a/src/2geom/svg-path-parser.h b/src/2geom/svg-path-parser.h index 60d8a078b..12e80df5a 100644 --- a/src/2geom/svg-path-parser.h +++ b/src/2geom/svg-path-parser.h @@ -1,5 +1,6 @@ -/* - * parse SVG path specifications +/** + * \file + * \brief parse SVG path specifications * * Copyright 2007 MenTaLguY * Copyright 2007 Aaron Spike diff --git a/src/2geom/svg-path.h b/src/2geom/svg-path.h index 6da5afb7e..f2902750c 100644 --- a/src/2geom/svg-path.h +++ b/src/2geom/svg-path.h @@ -1,5 +1,6 @@ -/* - * callback interface for SVG path data +/** + * \file + * \brief callback interface for SVG path data * * Copyright 2007 MenTaLguY * diff --git a/src/2geom/sweep.h b/src/2geom/sweep.h index 6500ccbc2..0214511ac 100644 --- a/src/2geom/sweep.h +++ b/src/2geom/sweep.h @@ -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__ diff --git a/src/2geom/transforms.h b/src/2geom/transforms.h index d21c5c617..ac5a775c4 100644 --- a/src/2geom/transforms.h +++ b/src/2geom/transforms.h @@ -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 diff --git a/src/2geom/utils.h b/src/2geom/utils.h index ac99b8b00..5ab191749 100644 --- a/src/2geom/utils.h +++ b/src/2geom/utils.h @@ -1,7 +1,9 @@ #ifndef LIB2GEOM_UTILS_HEADER #define LIB2GEOM_UTILS_HEADER -/** Various utility functions. +/** + * \file + * \brief Various utility functions. * * Copyright 2007 Johan Engelen * Copyright 2006 Michael G. Sloan diff --git a/src/livarot/PathCutting.cpp b/src/livarot/PathCutting.cpp index 09d6ffe24..0a367a1fe 100644 --- a/src/livarot/PathCutting.cpp +++ b/src/livarot/PathCutting.cpp @@ -401,7 +401,7 @@ void Path::AddCurve(Geom::Curve const &c) else if(Geom::SVGEllipticalArc const *svg_elliptical_arc = dynamic_cast(&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 diff --git a/src/main.cpp b/src/main.cpp index 03beb0734..229ef65f7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #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; } diff --git a/src/preferences.cpp b/src/preferences.cpp index e999182c7..8b8289849 100644 --- a/src/preferences.cpp +++ b/src/preferences.cpp @@ -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(d); + _ObserverData *priv_data = new _ObserverData; + priv_data->_node = node; + priv_data->_is_attr = !attr_key.empty(); + o._data = static_cast(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); } diff --git a/src/svg/path-string.h b/src/svg/path-string.h index d09d43b9d..01389a3d0 100644 --- a/src/svg/path-string.h +++ b/src/svg/path-string.h @@ -1,4 +1,4 @@ -/* +/** * Inkscape::SVG::PathString - builder for SVG path strings * * Copyright 2007 MenTaLguY @@ -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) diff --git a/src/svg/svg-path.cpp b/src/svg/svg-path.cpp index 334ba0c1a..88e340bd4 100644 --- a/src/svg/svg-path.cpp +++ b/src/svg/svg-path.cpp @@ -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(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() ); } -- 2.30.2