1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
// -*- related-file-name: "../../liblcdf/bezier.cc" -*-
#ifndef LCDF_BEZIER_HH
#define LCDF_BEZIER_HH
#include <lcdf/point.hh>
#include <lcdf/vector.hh>
#include <string.h>
class Bezier { public:
Bezier() : _bb(-1) { }
inline Bezier(Point p[4]) throw ();
inline Bezier(const Point &, const Point &, const Point &, const Point &) throw ();
const Point *points() const { return _p; }
const Point &point(int i) const { assert(i>=0&&i<4); return _p[i]; }
Point &mpoint(int i) { assert(i>=0&&i<4); _bb = -1; return _p[i]; }
void set_point(int i, const Point &p) { mpoint(i) = p; }
Point eval(double) const throw ();
bool is_flat(double) const throw ();
bool in_bb(const Point &, double) const throw ();
bool hit(const Point &, double) const throw ();
inline double bb_left() const throw ();
inline double bb_right() const throw ();
inline double bb_top() const throw ();
inline double bb_bottom() const throw ();
inline double bb_left_x() const throw ();
inline double bb_right_x() const throw ();
inline double bb_top_x() const throw ();
inline double bb_bottom_x() const throw ();
void halve(Bezier &, Bezier &) const throw ();
inline void segmentize(Vector<Point> &) const;
void segmentize(Vector<Point> &, bool) const;
static void fit(const Vector<Point> &, double, Vector<Bezier> &);
private:
Point _p[4];
mutable int _bb;
void make_bb() const throw ();
inline void ensure_bb() const throw ();
double hit_recurse(const Point &, double, double, double, double, double) const throw ();
};
inline
Bezier::Bezier(Point p[4]) throw ()
: _bb(-1)
{
memcpy(_p, p, sizeof(Point) * 4);
}
inline
Bezier::Bezier(const Point &p0, const Point &p1, const Point &p2, const Point &p3) throw ()
{
_p[0] = p0;
_p[1] = p1;
_p[2] = p2;
_p[3] = p3;
_bb = -1;
}
inline void
Bezier::ensure_bb() const throw ()
{
if (_bb < 0)
make_bb();
}
inline double
Bezier::bb_top_x() const throw ()
{
return _p[(_bb >> 4) & 3].y;
}
inline double
Bezier::bb_left_x() const throw ()
{
return _p[(_bb >> 2) & 3].x;
}
inline double
Bezier::bb_bottom_x() const throw ()
{
return _p[(_bb >> 6) & 3].y;
}
inline double
Bezier::bb_right_x() const throw ()
{
return _p[(_bb >> 0) & 3].x;
}
inline double
Bezier::bb_top() const throw ()
{
ensure_bb();
return bb_top_x();
}
inline double
Bezier::bb_left() const throw ()
{
ensure_bb();
return bb_left_x();
}
inline double
Bezier::bb_bottom() const throw ()
{
ensure_bb();
return bb_bottom_x();
}
inline double
Bezier::bb_right() const throw ()
{
ensure_bb();
return bb_right_x();
}
inline void
Bezier::segmentize(Vector<Point> &v) const
{
segmentize(v, v.size() == 0 || v.back() != _p[0]);
}
#endif
|