Common/Geom/Curve.h

Go to the documentation of this file.
00001 //-------------------------------------------------------------------
00004 // Copyright (c) 2004 Evan Sherbrooke and Michael Lauer 
00005 // Portions copyright (c) 2007 Celeritive Technologies, Inc.
00006 //
00007 // This library is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 2.1 of the License, or (at your option) any later version.
00011 //
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00015 // Lesser General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU Lesser General Public
00018 // License along with this library; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00020 //
00021 //-------------------------------------------------------------------
00022 #pragma once
00023 #ifndef VOLUMILL_CURVE_H
00024 #define VOLUMILL_CURVE_H
00025 
00026 #include <Geom/Points.h>
00027 #include <Geom/PointAlg.h>
00028 #include <Util/TypeStripper.h>
00029 #include <Util/Params.h>
00030 #include <boost/mpl/if.hpp>
00031 #include <boost/type_traits/is_base_of.hpp>
00032 #include <loki/Visitor.h>
00033 
00034 namespace geom
00035 {
00036 
00037 template <typename R, typename Visited>
00038 struct ThrowingCatchAll
00039 {
00040    static R OnUnknownVisitor(Visited&, Loki::BaseVisitor&)
00041    {
00042       VALIDATE(0)("Unknown Visitor type not supported right now");
00043    }
00044 };
00045 
00047 template <int n>
00048 class ParametricCurve : public Loki::BaseVisitable<void, Loki::DefaultCatchAll, true>, public util::Parameterized
00049 {
00050    friend class boost::serialization::access;
00051    template<class Archive>
00052    void serialize(Archive &ar, const unsigned int version)
00053    {
00054       if (version > 0)
00055          ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(util::Parameterized);
00056    }
00057 public:
00058    LOKI_DEFINE_CONST_VISITABLE();
00060    enum { Dim = n };
00062    typedef PointNd<n> Point;
00064    typedef VecNd<n> Vec;
00065 
00066    virtual ~ParametricCurve();
00067 
00070    virtual std::pair<double, double> getRange() const = 0;
00073    virtual bool isPeriodic() const = 0;
00080    virtual void evaluate(double param, Point *pPt, 
00081       int nderivs = 0, std::vector<Vec> *pDerivs = 0) const = 0;
00084    virtual shared_ptr<ParametricCurve<n> > clone() const = 0;
00086    virtual void reverse() = 0;
00087 };
00088 
00089 typedef shared_ptr<ParametricCurve<2> > CurvePtr2d;
00090 typedef shared_ptr<ParametricCurve<3> > CurvePtr3d;
00091 typedef std::vector<CurvePtr2d> CompositeCurve2d;
00092 typedef std::vector<CurvePtr3d> CompositeCurve3d;
00093 
00095 template <int n>
00096 class ControlPointCurveBase : virtual public ParametricCurve<n>
00097 {
00098 public:
00099    virtual ~ControlPointCurveBase();
00100 
00103    virtual int getNumCpts() const = 0;
00104 
00105    // Control points
00106    // Return by VALUE, because may be computed from homogeneous coords!
00110    virtual PointNd<n> getControlPoint(int i) const = 0;
00114    virtual void setControlPoint(int i, const PointNd<n> &pt) = 0;
00117    virtual double getWeight(int i) const = 0;
00118 };
00119 
00120 namespace detail
00121 {
00122    template<class Curve>
00123    struct CurveEndpointAccessor
00124    {
00125       typedef PointNd<Curve::Dim> Point;
00126       inline Point getStartPoint (const Curve& c)
00127       {
00128          Point pt;
00129          c.evaluate (0.0, &pt);
00130          return pt;
00131       }
00132       inline Point getEndPoint (const Curve& c)
00133       {
00134          Point pt;
00135          c.evaluate (1.0, &pt);
00136          return pt;
00137       }
00138    };
00139 
00140    template<int n>
00141    struct CurveEndpointAccessor<ControlPointCurveBase<n> >
00142    {
00143       typedef PointNd<n> Point;
00144       typedef ControlPointCurveBase<n> Curve;
00145       inline Point getStartPoint (const Curve& c)
00146       {
00147          return c.getControlPoint (0);
00148       }
00149       inline Point getEndPoint (const Curve& c)
00150       {
00151          return c.getControlPoint (c.getNumCpts() - 1);
00152       }
00153       inline void setStartPoint (Curve& c, const Point& pt)
00154       {
00155          c.setControlPoint (0, pt);
00156       }
00157       inline void setEndPoint (Curve& c, const Point& pt)
00158       {
00159          c.setControlPoint (c.getNumCpts() - 1, pt);
00160       }
00161    };
00162 }
00163 
00164 template<class T>
00165 inline PointNd<util::TypeStripper<T>::base_type::Dim>
00166 getStartPoint (T curve)
00167 {
00168    typedef typename util::TypeStripper<T>::base_type Derived;
00169    typedef ControlPointCurveBase<Derived::Dim> Base;
00170    typedef typename boost::mpl::if_<boost::is_base_of<Base, Derived>,
00171       Base,
00172       Derived>::type Arg;
00173    detail::CurveEndpointAccessor<Arg> cea;
00174    return cea.getStartPoint (util::TypeStripper<T>::cstrip (curve));
00175 }
00176 
00177 template<class T>
00178 inline PointNd<util::TypeStripper<T>::base_type::Dim>
00179 getEndPoint (T curve)
00180 {
00181    typedef typename util::TypeStripper<T>::base_type Derived;
00182    typedef ControlPointCurveBase<Derived::Dim> Base;
00183    typedef typename boost::mpl::if_<boost::is_base_of<Base, Derived>,
00184       Base,
00185       Derived>::type Arg;
00186    detail::CurveEndpointAccessor<Arg> cea;
00187    return cea.getEndPoint (util::TypeStripper<T>::cstrip (curve));
00188 }
00189 
00190 template<class T, class P>
00191 inline void setStartPoint (T curve, const P& pt)
00192 {
00193    typedef typename util::TypeStripper<T>::base_type Derived;
00194    typedef ControlPointCurveBase<Derived::Dim> Base;
00195    typedef typename boost::mpl::if_<boost::is_base_of<Base, Derived>,
00196       Base,
00197       Derived>::type Arg;
00198    detail::CurveEndpointAccessor<Arg> cea;
00199    cea.setStartPoint (util::TypeStripper<T>::strip (curve), pt);
00200 }
00201 
00202 template<class T, class P>
00203 inline void setEndPoint (T curve, const P& pt)
00204 {
00205    typedef typename util::TypeStripper<T>::base_type Derived;
00206    typedef ControlPointCurveBase<Derived::Dim> Base;
00207    typedef typename boost::mpl::if_<boost::is_base_of<Base, Derived>,
00208       Base,
00209       Derived>::type Arg;
00210    detail::CurveEndpointAccessor<Arg> cea;
00211    cea.setEndPoint (util::TypeStripper<T>::strip (curve), pt);
00212 }
00213 
00215 template <int n>
00216 class Line : virtual public ControlPointCurveBase<n>
00217 {
00218 public:
00219    // GCC bug
00220    typedef void ReturnType;
00221    LOKI_DEFINE_CONST_VISITABLE();
00222 };
00223 
00224 template<int n>
00225 shared_ptr<Line<n> > makeLine ();
00226 
00227 template <int n>
00228 inline shared_ptr<Line<n> > makeLine (const PointNd<n>& start, const PointNd<n>& end)
00229 {
00230    shared_ptr<Line<n> > pLine (makeLine<n>());
00231    setStartPoint (pLine, start);
00232    setEndPoint (pLine, end);
00233 //   WARN (length (VecNd<n> (end-start)) > util::doubleEps);
00234    return pLine;
00235 }
00236 
00237 
00238 typedef Line<2> Line2d;
00239 typedef Line<3> Line3d;
00240 
00242 template <int n>
00243 class Polyline : virtual public ControlPointCurveBase<n>
00244 {
00245 public:
00246    // GCC bug
00247    typedef void ReturnType;
00248    LOKI_DEFINE_CONST_VISITABLE();
00249 
00250    virtual int getSpan (double param) const = 0;
00251    virtual const std::vector<geom::PointNd<n> >& getPts() const = 0;
00252 };
00253 
00254 template<int n>
00255 shared_ptr<Polyline<n> > makePolyline (const std::vector<geom::PointNd<n> >& pts);
00256 
00257 typedef Polyline<2> Polyline2d;
00258 typedef Polyline<3> Polyline3d;
00259 
00261 template <int n>
00262 class Arc
00263 {
00264 };
00265 
00266 template<>
00267 class Arc<2> : virtual public ParametricCurve<2>
00268 {
00269 public:
00270    LOKI_DEFINE_CONST_VISITABLE();
00271    virtual const Point2d& getCenter() const = 0;
00272    virtual double getRadius() const = 0;
00273    virtual const std::pair<double, double>& getAngleRange() const = 0;
00274    virtual bool isCCW() const = 0;
00275 
00276    virtual void assign (const Arc<2>& otherArc) = 0;
00277 };
00278 
00281 shared_ptr<Arc<2> > makeArc (const Point2d& center, double radius, double startAngle, double endAngle);
00282 shared_ptr<Arc<2> > makeCCWArcCenter (const Point2d& center, const Point2d& startPt, const Point2d& endPt);
00283 shared_ptr<Arc<2> > makeCCWArcCenterRadius (
00284    const Point2d& center, const Point2d& startPt, const Point2d& endPt, double radius);
00285 shared_ptr<Arc<2> > makeCWArcCenter (const Point2d& center, const Point2d& startPt, const Point2d& endPt);
00286 shared_ptr<Arc<2> > makeCircle (const Point2d& center, double radius);
00287 CurvePtr2d makeArcTangents (const Point2d& startPt, const Point2d& commonTan, const Point2d& endPt);
00288 typedef Arc<2> Arc2d;
00289 typedef Arc<3> Arc3d;
00290 
00291 }
00292 
00293 BOOST_IS_ABSTRACT (geom::ParametricCurve<2>);
00294 BOOST_IS_ABSTRACT (geom::ParametricCurve<3>);
00295 
00296 BOOST_CLASS_VERSION (geom::ParametricCurve<2>, 1);
00297 BOOST_CLASS_VERSION (geom::ParametricCurve<3>, 1);
00298 #endif

Generated on Tue Jan 29 21:37:56 2008 for VoluMill Universal Client by  doxygen 1.4.6