index b3c20037897aece708fcd63014d61d7d20251ef2..66de31d70364b8ef4f0071d51db8bd7385e20042 100644 (file)
#define _2GEOM_HVLINESEGMENT_H_
-#include "bezier-curve.h"
+#include <2geom/bezier-curve.h>
namespace Geom
class HLineSegment : public Curve
{
public:
- HLineSegment()
- {}
-
- HLineSegment(Coord _x0, Coord _x1, Coord _y)
- : m_line_seg(Point(_x0, _y), Point(_x1, _y))
- {
- }
-
- HLineSegment(Point const& _p, double _length)
- : m_line_seg(_p, Point(_p[X] + _length, _p[Y]))
- {
- }
-
- HLineSegment(Point const& _p0, Point const& _p1)
- : m_line_seg(_p0, _p1)
- {
- if ( _p0[Y] != _p1[Y] )
- {
- THROW_RANGEERROR("HLineSegment::HLineSegment passed points should "
- "have the same Y value");
- }
- }
-
- Curve* duplicate() const
- {
- return new HLineSegment(*this);
- }
-
- bool isDegenerate() const
- {
- return m_line_seg.isDegenerate();
- }
-
- Point initialPoint() const
- {
- return m_line_seg.initialPoint();
- }
-
- Point finalPoint() const
- {
- return m_line_seg.finalPoint();
- }
-
- Coord getY()
- {
- return initialPoint()[Y];
- }
-
- void setInitial(Point _p)
- {
- m_line_seg.setInitial( Point(_p[X], initialPoint()[Y]) );
- }
-
- void setFinal(Point _p)
- {
- m_line_seg.setFinal( Point(_p[X], finalPoint()[Y]) );
- }
-
- void setX0(Coord _x)
- {
- m_line_seg.setInitial( Point(_x, initialPoint()[Y]) );
- }
-
- void setX1(Coord _x)
- {
- m_line_seg.setFinal( Point(_x, finalPoint()[Y]) );
- }
-
- void setY(Coord _y)
- {
- m_line_seg.setInitial( Point(initialPoint()[X], _y) );
- m_line_seg.setFinal( Point(finalPoint()[X], _y) );
- }
-
- Rect boundsFast() const
- {
- return boundsExact();
- }
-
- Rect boundsExact() const
- {
- return Rect( initialPoint(), finalPoint() );
- }
-
- Rect boundsLocal(Interval i, unsigned deg) const
- {
- return m_line_seg.boundsLocal(i, deg);
- }
-
- int winding(Point p) const
- {
- return m_line_seg.winding(p);
- }
-
- std::vector<double>
- roots(double v, Dim2 d) const
- {
- if (d < 0 || d > 1)
- {
- THROW_RANGEERROR("dimension argument out of range");
- }
- std::vector<double> result;
- if (d == X)
- {
- if ( v >= initialPoint()[X] && v <= finalPoint()[X] )
- {
- double t = 0;
- if (!isDegenerate())
- t = (v - initialPoint()[X]) / (finalPoint()[X] - initialPoint()[X]);
- result.push_back(t);
- }
- }
- else
- {
- if (v == initialPoint()[Y])
- {
- if (!isDegenerate())
- THROW_INFINITESOLUTIONS(0);
- result.push_back(0);
- }
- }
- return result;
- }
-
- double nearestPoint( Point const& p, double from = 0, double to = 1 ) const
- {
- if ( from > to ) std::swap(from, to);
- double xfrom = pointAt(from)[X];
- double xto = pointAt(to)[X];
- if ( xfrom > xto )
- {
- std::swap(xfrom, xto);
- std::swap(from, to);
- }
- if ( p[X] > xfrom && p[X] < xto )
- {
- return (p[X] - initialPoint()[X]) / (finalPoint()[X] - initialPoint()[X]);
- }
- else if ( p[X] <= xfrom )
- return from;
- else
- return to;
- }
-
- std::pair<HLineSegment, HLineSegment> subdivide(Coord t) const
- {
- std::pair<HLineSegment, HLineSegment> result;
- Point p = pointAt(t);
- result.first.setInitial(initialPoint());
- result.first.setFinal(p);
- result.second.setInitial(p);
- result.second.setFinal(finalPoint());
- return result;
- }
-
- Curve* portion(double f, double t) const
- {
- Point ip = pointAt(f);
- Point ep = pointAt(t);
- return new HLineSegment(ip[X], ep[X], ip[Y]);
- }
-
- Curve* reverse() const
- {
- return
- new HLineSegment(finalPoint()[X], initialPoint()[X], initialPoint()[Y]);
- }
-
- Curve* transformed(Matrix const & m) const
- {
- Point ip = initialPoint() * m;
- Point ep = finalPoint() * m;
- return new LineSegment(ip, ep);
- }
-
- Curve* derivative() const
- {
- double x = finalPoint()[X] - initialPoint()[X];
- return new HLineSegment(x, x, 0);
- }
-
- Point pointAt(double t) const
- {
- if ( t < 0 || t > 1 )
- THROW_RANGEERROR("domain parameter out of range");
- double x = initialPoint()[X] + t * (finalPoint()[X] - initialPoint()[X]);
- return Point(x, initialPoint()[Y]);
- }
-
- double valueAt(double t, Dim2 d) const
- {
- if (d < 0 || d > 1)
- {
- THROW_RANGEERROR("dimension argument out of range");
- }
- if ( t < 0 || t > 1 )
- THROW_RANGEERROR("domain parameter out of range");
-
- if (d == Y) return initialPoint()[Y];
-
- return initialPoint()[X] + t * (finalPoint()[X] - initialPoint()[X]);
- }
-
- std::vector<Point> pointAndDerivatives(Coord t, unsigned n) const
- {
- std::vector<Point> result;
- if ( n > 0)
- result.push_back(pointAt(t));
- if (n > 1)
- {
- double x = finalPoint()[X] - initialPoint()[X];
- result.push_back( Point(x, 0) );
- }
- return result;
- }
-
- D2<SBasis> toSBasis() const
- {
- return m_line_seg.toSBasis();
- }
-
+ HLineSegment()
+ {}
+
+ HLineSegment(Coord _x0, Coord _x1, Coord _y)
+ : m_line_seg(Point(_x0, _y), Point(_x1, _y))
+ {
+ }
+
+ HLineSegment(Point const& _p, double _length)
+ : m_line_seg(_p, Point(_p[X] + _length, _p[Y]))
+ {
+ }
+
+ HLineSegment(Point const& _p0, Point const& _p1)
+ : m_line_seg(_p0, _p1)
+ {
+ if ( _p0[Y] != _p1[Y] )
+ {
+ THROW_RANGEERROR("HLineSegment::HLineSegment passed points should "
+ "have the same Y value");
+ }
+ }
+
+ Curve* duplicate() const
+ {
+ return new HLineSegment(*this);
+ }
+
+ bool isDegenerate() const
+ {
+ return m_line_seg.isDegenerate();
+ }
+
+ Point initialPoint() const
+ {
+ return m_line_seg.initialPoint();
+ }
+
+ Point finalPoint() const
+ {
+ return m_line_seg.finalPoint();
+ }
+
+ Coord getY()
+ {
+ return initialPoint()[Y];
+ }
+
+ void setInitial(Point _p)
+ {
+ m_line_seg.setInitial( Point(_p[X], initialPoint()[Y]) );
+ }
+
+ void setFinal(Point _p)
+ {
+ m_line_seg.setFinal( Point(_p[X], finalPoint()[Y]) );
+ }
+
+ void setX0(Coord _x)
+ {
+ m_line_seg.setInitial( Point(_x, initialPoint()[Y]) );
+ }
+
+ void setX1(Coord _x)
+ {
+ m_line_seg.setFinal( Point(_x, finalPoint()[Y]) );
+ }
+
+ void setY(Coord _y)
+ {
+ m_line_seg.setInitial( Point(initialPoint()[X], _y) );
+ m_line_seg.setFinal( Point(finalPoint()[X], _y) );
+ }
+
+ Rect boundsFast() const
+ {
+ return boundsExact();
+ }
+
+ Rect boundsExact() const
+ {
+ return Rect( initialPoint(), finalPoint() );
+ }
+
+ Rect boundsLocal(Interval i, unsigned deg) const
+ {
+ return m_line_seg.boundsLocal(i, deg);
+ }
+
+ int winding(Point p) const
+ {
+ return m_line_seg.winding(p);
+ }
+
+ std::vector<double>
+ roots(double v, Dim2 d) const
+ {
+ if (d < 0 || d > 1)
+ {
+ THROW_RANGEERROR("dimension argument out of range");
+ }
+ std::vector<double> result;
+ if (d == X)
+ {
+ if ( v >= initialPoint()[X] && v <= finalPoint()[X] )
+ {
+ double t = 0;
+ if (!isDegenerate())
+ t = (v - initialPoint()[X]) / (finalPoint()[X] - initialPoint()[X]);
+ result.push_back(t);
+ }
+ }
+ else
+ {
+ if (v == initialPoint()[Y])
+ {
+ if (!isDegenerate())
+ THROW_INFINITESOLUTIONS(0);
+ result.push_back(0);
+ }
+ }
+ return result;
+ }
+
+ double nearestPoint( Point const& p, double from = 0, double to = 1 ) const
+ {
+ if ( from > to ) std::swap(from, to);
+ double xfrom = pointAt(from)[X];
+ double xto = pointAt(to)[X];
+ if ( xfrom > xto )
+ {
+ std::swap(xfrom, xto);
+ std::swap(from, to);
+ }
+ if ( p[X] > xfrom && p[X] < xto )
+ {
+ return (p[X] - initialPoint()[X]) / (finalPoint()[X] - initialPoint()[X]);
+ }
+ else if ( p[X] <= xfrom )
+ return from;
+ else
+ return to;
+ }
+
+ std::pair<HLineSegment, HLineSegment> subdivide(Coord t) const
+ {
+ std::pair<HLineSegment, HLineSegment> result;
+ Point p = pointAt(t);
+ result.first.setInitial(initialPoint());
+ result.first.setFinal(p);
+ result.second.setInitial(p);
+ result.second.setFinal(finalPoint());
+ return result;
+ }
+
+ Curve* portion(double f, double t) const
+ {
+ Point ip = pointAt(f);
+ Point ep = pointAt(t);
+ return new HLineSegment(ip[X], ep[X], ip[Y]);
+ }
+
+ Curve* reverse() const
+ {
+ return
+ new HLineSegment(finalPoint()[X], initialPoint()[X], initialPoint()[Y]);
+ }
+
+ Curve* transformed(Matrix const & m) const
+ {
+ Point ip = initialPoint() * m;
+ Point ep = finalPoint() * m;
+ if (m.onlyScaleAndTranslation()) {
+ return new HLineSegment(ip[X], ep[X], ip[Y]);
+ } else {
+ return new LineSegment(ip, ep);
+ }
+ }
+
+ Curve* derivative() const
+ {
+ double x = finalPoint()[X] - initialPoint()[X];
+ return new HLineSegment(x, x, 0);
+ }
+
+ Point pointAt(double t) const
+ {
+ if ( t < 0 || t > 1 )
+ THROW_RANGEERROR("domain parameter out of range");
+ double x = initialPoint()[X] + t * (finalPoint()[X] - initialPoint()[X]);
+ return Point(x, initialPoint()[Y]);
+ }
+
+ double valueAt(double t, Dim2 d) const
+ {
+ if (d < 0 || d > 1)
+ {
+ THROW_RANGEERROR("dimension argument out of range");
+ }
+ if ( t < 0 || t > 1 )
+ THROW_RANGEERROR("domain parameter out of range");
+
+ if (d == Y) return initialPoint()[Y];
+
+ return initialPoint()[X] + t * (finalPoint()[X] - initialPoint()[X]);
+ }
+
+ std::vector<Point> pointAndDerivatives(Coord t, unsigned n) const
+ {
+ std::vector<Point> result;
+ result.push_back(pointAt(t));
+ if (n > 0)
+ {
+ double x = finalPoint()[X] - initialPoint()[X];
+ result.push_back( Point(x, 0) );
+ }
+ if (n > 1)
+ {
+ /* higher order derivatives are zero,
+ * so the other n-1 vector elements are (0,0) */
+ result.insert( result.end(), n-1, Point(0, 0) );
+ }
+ return result;
+ }
+
+ D2<SBasis> toSBasis() const
+ {
+ return m_line_seg.toSBasis();
+ }
+
private:
- LineSegment m_line_seg;
-
+ LineSegment m_line_seg;
+
}; // end class HLineSegment
class VLineSegment : public Curve
{
public:
- VLineSegment()
- {}
-
- VLineSegment(Coord _x, Coord _y0, Coord _y1)
- : m_line_seg(Point(_x, _y0), Point(_x, _y1))
- {
- }
-
- VLineSegment(Point const& _p, double _length)
- : m_line_seg(_p, Point(_p[X], _p[Y] + _length))
- {
- }
-
- VLineSegment(Point const& _p0, Point const& _p1)
- : m_line_seg(_p0, _p1)
- {
- if ( _p0[X] != _p1[X] )
- {
- THROW_RANGEERROR("VLineSegment::VLineSegment passed points should "
- "have the same X value");
- }
- }
-
- Curve* duplicate() const
- {
- return new VLineSegment(*this);
- }
-
- bool isDegenerate() const
- {
- return m_line_seg.isDegenerate();
- }
-
- Point initialPoint() const
- {
- return m_line_seg.initialPoint();
- }
-
- Point finalPoint() const
- {
- return m_line_seg.finalPoint();
- }
-
- Coord getX()
- {
- return initialPoint()[X];
- }
-
- void setInitial(Point _p)
- {
- m_line_seg.setInitial( Point(initialPoint()[X], _p[Y]) );
- }
-
- void setFinal(Point _p)
- {
- m_line_seg.setFinal( Point(finalPoint()[X], _p[Y]) );
- }
-
- void setY0(Coord _y)
- {
- m_line_seg.setInitial( Point(initialPoint()[X], _y) );
- }
-
- void setY1(Coord _y)
- {
- m_line_seg.setFinal( Point(finalPoint()[Y], _y) );
- }
-
- void setX(Coord _x)
- {
- m_line_seg.setInitial( Point(_x, initialPoint()[Y]) );
- m_line_seg.setFinal( Point(_x, finalPoint()[Y]) );
- }
-
- Rect boundsFast() const
- {
- return boundsExact();
- }
-
- Rect boundsExact() const
- {
- return Rect( initialPoint(), finalPoint() );
- }
-
- Rect boundsLocal(Interval i, unsigned deg) const
- {
- return m_line_seg.boundsLocal(i, deg);
- }
-
- int winding(Point p) const
- {
- return m_line_seg.winding(p);
- }
-
- std::vector<double>
- roots(double v, Dim2 d) const
- {
- if (d < 0 || d > 1)
- {
- THROW_RANGEERROR("dimension argument out of range");
- }
- std::vector<double> result;
- if (d == Y)
- {
- if ( v >= initialPoint()[Y] && v <= finalPoint()[Y] )
- {
- double t = 0;
- if (!isDegenerate())
- t = (v - initialPoint()[Y]) / (finalPoint()[Y] - initialPoint()[Y]);
- result.push_back(t);
- }
- }
- else
- {
- if (v == initialPoint()[X])
- {
- if (!isDegenerate())
- THROW_INFINITESOLUTIONS(0);
- result.push_back(0);
- }
- }
- return result;
- }
-
- double nearestPoint( Point const& p, double from = 0, double to = 1 ) const
- {
- if ( from > to ) std::swap(from, to);
- double yfrom = pointAt(from)[Y];
- double yto = pointAt(to)[Y];
- if (yfrom > yto)
- {
- std::swap(yfrom, yto);
- std::swap(from, to);
- }
- if ( p[Y] > yfrom && p[Y] < yto )
- {
- return (p[Y] - initialPoint()[Y]) / (finalPoint()[Y] - initialPoint()[Y]);
- }
- else if ( p[Y] <= yfrom )
- return from;
- else
- return to;
- }
-
- std::pair<VLineSegment, VLineSegment> subdivide(Coord t) const
- {
- std::pair<VLineSegment, VLineSegment> result;
- Point p = pointAt(t);
- result.first.setInitial(initialPoint());
- result.first.setFinal(p);
- result.second.setInitial(p);
- result.second.setFinal(finalPoint());
- return result;
- }
-
- Curve* portion(double f, double t) const
- {
- Point ip = pointAt(f);
- Point ep = pointAt(t);
- return new VLineSegment(ip[X], ip[Y], ep[Y]);
- }
-
- Curve* reverse() const
- {
- return
- new VLineSegment(initialPoint()[X], finalPoint()[Y], initialPoint()[Y]);
- }
-
- Curve* transformed(Matrix const & m) const
- {
- Point ip = initialPoint() * m;
- Point ep = finalPoint() * m;
- return new LineSegment(ip, ep);
- }
-
- Curve* derivative() const
- {
- double y = finalPoint()[Y] - initialPoint()[Y];
- return new VLineSegment(0, y, y);
- }
-
- Point pointAt(double t) const
- {
- if ( t < 0 || t > 1 )
- THROW_RANGEERROR("domain parameter out of range");
- double y = initialPoint()[Y] + t * (finalPoint()[Y] - initialPoint()[Y]);
- return Point(initialPoint()[X], y);
- }
-
- double valueAt(double t, Dim2 d) const
- {
- if (d < 0 || d > 1)
- {
- THROW_RANGEERROR("dimension argument out of range");
- }
- if ( t < 0 || t > 1 )
- THROW_RANGEERROR("domain parameter out of range");
-
- if (d == X) return initialPoint()[X];
-
- return initialPoint()[Y] + t * (finalPoint()[Y] - initialPoint()[Y]);
- }
-
- std::vector<Point> pointAndDerivatives(Coord t, unsigned n) const
- {
- std::vector<Point> result;
- if ( n > 0)
- result.push_back(pointAt(t));
- if (n > 1)
- {
- double y = finalPoint()[Y] - initialPoint()[Y];
- result.push_back( Point(0, y) );
- }
- return result;
- }
-
- D2<SBasis> toSBasis() const
- {
- return m_line_seg.toSBasis();
- }
-
+ VLineSegment()
+ {}
+
+ VLineSegment(Coord _x, Coord _y0, Coord _y1)
+ : m_line_seg(Point(_x, _y0), Point(_x, _y1))
+ {
+ }
+
+ VLineSegment(Point const& _p, double _length)
+ : m_line_seg(_p, Point(_p[X], _p[Y] + _length))
+ {
+ }
+
+ VLineSegment(Point const& _p0, Point const& _p1)
+ : m_line_seg(_p0, _p1)
+ {
+ if ( _p0[X] != _p1[X] )
+ {
+ THROW_RANGEERROR("VLineSegment::VLineSegment passed points should "
+ "have the same X value");
+ }
+ }
+
+ Curve* duplicate() const
+ {
+ return new VLineSegment(*this);
+ }
+
+ bool isDegenerate() const
+ {
+ return m_line_seg.isDegenerate();
+ }
+
+ Point initialPoint() const
+ {
+ return m_line_seg.initialPoint();
+ }
+
+ Point finalPoint() const
+ {
+ return m_line_seg.finalPoint();
+ }
+
+ Coord getX()
+ {
+ return initialPoint()[X];
+ }
+
+ void setInitial(Point _p)
+ {
+ m_line_seg.setInitial( Point(initialPoint()[X], _p[Y]) );
+ }
+
+ void setFinal(Point _p)
+ {
+ m_line_seg.setFinal( Point(finalPoint()[X], _p[Y]) );
+ }
+
+ void setY0(Coord _y)
+ {
+ m_line_seg.setInitial( Point(initialPoint()[X], _y) );
+ }
+
+ void setY1(Coord _y)
+ {
+ m_line_seg.setFinal( Point(finalPoint()[Y], _y) );
+ }
+
+ void setX(Coord _x)
+ {
+ m_line_seg.setInitial( Point(_x, initialPoint()[Y]) );
+ m_line_seg.setFinal( Point(_x, finalPoint()[Y]) );
+ }
+
+ Rect boundsFast() const
+ {
+ return boundsExact();
+ }
+
+ Rect boundsExact() const
+ {
+ return Rect( initialPoint(), finalPoint() );
+ }
+
+ Rect boundsLocal(Interval i, unsigned deg) const
+ {
+ return m_line_seg.boundsLocal(i, deg);
+ }
+
+ int winding(Point p) const
+ {
+ return m_line_seg.winding(p);
+ }
+
+ std::vector<double>
+ roots(double v, Dim2 d) const
+ {
+ if (d < 0 || d > 1)
+ {
+ THROW_RANGEERROR("dimension argument out of range");
+ }
+ std::vector<double> result;
+ if (d == Y)
+ {
+ if ( v >= initialPoint()[Y] && v <= finalPoint()[Y] )
+ {
+ double t = 0;
+ if (!isDegenerate())
+ t = (v - initialPoint()[Y]) / (finalPoint()[Y] - initialPoint()[Y]);
+ result.push_back(t);
+ }
+ }
+ else
+ {
+ if (v == initialPoint()[X])
+ {
+ if (!isDegenerate())
+ THROW_INFINITESOLUTIONS(0);
+ result.push_back(0);
+ }
+ }
+ return result;
+ }
+
+ double nearestPoint( Point const& p, double from = 0, double to = 1 ) const
+ {
+ if ( from > to ) std::swap(from, to);
+ double yfrom = pointAt(from)[Y];
+ double yto = pointAt(to)[Y];
+ if (yfrom > yto)
+ {
+ std::swap(yfrom, yto);
+ std::swap(from, to);
+ }
+ if ( p[Y] > yfrom && p[Y] < yto )
+ {
+ return (p[Y] - initialPoint()[Y]) / (finalPoint()[Y] - initialPoint()[Y]);
+ }
+ else if ( p[Y] <= yfrom )
+ return from;
+ else
+ return to;
+ }
+
+ std::pair<VLineSegment, VLineSegment> subdivide(Coord t) const
+ {
+ std::pair<VLineSegment, VLineSegment> result;
+ Point p = pointAt(t);
+ result.first.setInitial(initialPoint());
+ result.first.setFinal(p);
+ result.second.setInitial(p);
+ result.second.setFinal(finalPoint());
+ return result;
+ }
+
+ Curve* portion(double f, double t) const
+ {
+ Point ip = pointAt(f);
+ Point ep = pointAt(t);
+ return new VLineSegment(ip[X], ip[Y], ep[Y]);
+ }
+
+ Curve* reverse() const
+ {
+ return
+ new VLineSegment(initialPoint()[X], finalPoint()[Y], initialPoint()[Y]);
+ }
+
+ Curve* transformed(Matrix const & m) const
+ {
+ Point ip = initialPoint() * m;
+ Point ep = finalPoint() * m;
+ if (m.onlyScaleAndTranslation()) {
+ return new VLineSegment(ip[X], ip[Y], ep[Y]);
+ } else {
+ return new LineSegment(ip, ep);
+ }
+ }
+
+ Curve* derivative() const
+ {
+ double y = finalPoint()[Y] - initialPoint()[Y];
+ return new VLineSegment(0, y, y);
+ }
+
+ Point pointAt(double t) const
+ {
+ if ( t < 0 || t > 1 )
+ THROW_RANGEERROR("domain parameter out of range");
+ double y = initialPoint()[Y] + t * (finalPoint()[Y] - initialPoint()[Y]);
+ return Point(initialPoint()[X], y);
+ }
+
+ double valueAt(double t, Dim2 d) const
+ {
+ if (d < 0 || d > 1)
+ {
+ THROW_RANGEERROR("dimension argument out of range");
+ }
+ if ( t < 0 || t > 1 )
+ THROW_RANGEERROR("domain parameter out of range");
+
+ if (d == X) return initialPoint()[X];
+
+ return initialPoint()[Y] + t * (finalPoint()[Y] - initialPoint()[Y]);
+ }
+
+ std::vector<Point> pointAndDerivatives(Coord t, unsigned n) const
+ {
+ std::vector<Point> result;
+ result.push_back(pointAt(t));
+ if (n > 0)
+ {
+ double y = finalPoint()[Y] - initialPoint()[Y];
+ result.push_back( Point(0, y) );
+ }
+ if (n > 1)
+ {
+ /* higher order derivatives are zero,
+ * so the other n-1 vector elements are (0,0) */
+ result.insert( result.end(), n-1, Point(0, 0) );
+ }
+ return result;
+ }
+
+ D2<SBasis> toSBasis() const
+ {
+ return m_line_seg.toSBasis();
+ }
+
private:
- LineSegment m_line_seg;
-
+ LineSegment m_line_seg;
+
}; // end class VLineSegment
} // end namespace Geom
-#endif // _2GEOM_HVLINESEGMENT_H_
+#endif // _2GEOM_HVLINESEGMENT_H_
/*