大家好,欢迎来到IT知识分享网。
定义Bezier类,这是为了能绘制曲线才定义的类。Bezier对象中有一个Polyline对象来表示贝塞尔曲线的形状,而Bezier本身的点则表示控制点。为了降低性能开销,仅在构造Bezier和修改Bezier控制点时重新计算贝塞尔曲线的形状,变换Bezier时,分别对Bezier本身的点和其中的Polyline的点做变换,而不重新计算形状。
下面给出Bezier的声明。
class Bezier : public Polyline { private: size_t _order = 2; Polyline _shape; public: Bezier(const size_t n); Bezier(const Bezier &bezier); Bezier(std::vector<Point>::const_iterator begin, std::vector<Point>::const_iterator end, const size_t n); Bezier(const std::initializer_list<Point> &points, const size_t n); const Type type() const override; // 贝塞尔曲线阶数 const size_t &order() const; const Polyline &shape() const; void update_shape(const double step = 0.01); void append_shape(const double step = 0.01); const double length() const override; void clear() override; Bezier *clone() const override; Bezier &operator=(const Bezier &bezier); void transform(const double a, const double b, const double c, const double d, const double e, const double f) override; void transform(const double mat[6]) override; void translate(const double tx, const double ty) override; void rotate(const double x, const double y, const double rad) override; void scale(const double x, const double y, const double k) override; Polygon convex_hull() const override; AABBRect bounding_rect() const override; Polygon mini_bounding_rect() const override; };
下面给出Bezier的实现。
Bezier::Bezier(const size_t n) : _order(n) { _shape.shape_fixed = true; } Bezier::Bezier(const Bezier &bezier) : Polyline(bezier), _order(bezier._order), _shape(bezier._shape) { _shape.shape_fixed = true; } Bezier::Bezier(std::vector<Point>::const_iterator begin, std::vector<Point>::const_iterator end, const size_t n) : Polyline(begin, end), _order(n) { _shape.shape_fixed = true; update_shape(); } Bezier::Bezier(const std::initializer_list<Point> &points, const size_t n) : Polyline(points), _order(n) { _shape.shape_fixed = true; update_shape(); } const Type Bezier::type() const { return Type::BEZIER; } const size_t &Bezier::order() const { return _order; } const Polyline &Bezier::shape() const { return _shape; } void Bezier::update_shape(const double step) { assert(0 < step && step < 1); _shape.clear(); std::vector<int> temp(1, 1), nums(_order + 1, 1); for (size_t i = 1; i <= _order; ++i) { for (size_t j = 1; j < i; ++j) { nums[j] = temp[j - 1] + temp[j]; } temp.assign(nums.begin(), nums.begin() + i + 1); } double t = 0; Point point; for (size_t i = 0, end = _points.size() - _order; i < end; i += _order) { _shape.append(_points[i]); t = 0; while (t <= 1) { point.clear(); for (size_t j = 0; j <= _order; ++j) { point += (_points[j + i] * (nums[j] * std::pow(1 - t, _order - j) * std::pow(t, j))); } _shape.append(point); t += step; } } _shape.append(_points.back()); } void Bezier::append_shape(const double step) { assert(0 < step && step < 1); if ((_points.size() - 1) % _order > 0) { return; } std::vector<int> temp(1, 1), nums(_order + 1, 1); for (size_t i = 1; i <= _order; ++i) { for (size_t j = 1; j < i; ++j) { nums[j] = temp[j - 1] + temp[j]; } temp.assign(nums.begin(), nums.begin() + i + 1); } double t = 0; Point point; const size_t i = _points.size() - _order - 1; while (t <= 1) { point.clear(); for (size_t j = 0; j <= _order; ++j) { point += (_points[j + i] * (nums[j] * std::pow(1 - t, _order - j) * std::pow(t, j))); } _shape.append(point); t += step; } _shape.append(_points.back()); } const double Bezier::length() const { return _shape.length(); } void Bezier::clear() { _shape.clear(); Polyline::clear(); } Bezier *Bezier::clone() const { return new Bezier(*this); } Bezier &Bezier::operator=(const Bezier &bezier) { if (this != &bezier) { Polyline::operator=(bezier); _shape = bezier._shape; } return *this; } void Bezier::transform(const double a, const double b, const double c, const double d, const double e, const double f) { Polyline::transform(a, b, c, d, e, f); _shape.transform(a, b, c, d, e, f); } void Bezier::transform(const double mat[6]) { Polyline::transform(mat); _shape.transform(mat); } void Bezier::translate(const double tx, const double ty) { Polyline::translate(tx, ty); _shape.translate(tx, ty); } void Bezier::rotate(const double x, const double y, const double rad) { Polyline::rotate(x, y, rad); _shape.rotate(x, y, rad); } void Bezier::scale(const double x, const double y, const double k) { Polyline::scale(x, y, k); _shape.scale(x, y, k); } Polygon Bezier::convex_hull() const { return _shape.convex_hull(); } AABBRect Bezier::bounding_rect() const { return _shape.bounding_rect(); } Polygon Bezier::mini_bounding_rect() const { return _shape.mini_bounding_rect(); }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/133283.html