C++实现贝塞尔曲线
已经存在许多讲解得比较清楚的解释。如https://www.jianshu.com/p/0c9b4b681724
贝塞尔曲线包含多阶。贝塞尔曲线的阶数和次数是一样的,二阶贝塞尔,三个点,最高次数二次。例:二阶贝塞尔:三个点,两个线段,以所有等比的点组合成的曲线叫做二阶贝塞尔曲线。如下图。
根据贝塞尔曲线的公式直接根据控制点缺点阶数,。
定义.h头文件
class Bezier {
public:
Bezier() = default;
const std::vector<hybrid_astar::Vector2D>& CalculateSpline(
const std::vector<hybrid_astar::Vector2D>& control_points,
const int& points_number);
void CalculateSecond();
void CalculateCubic();
private:
int ctrl_num_; //控制点数量
int order_; //阶数,表示曲线为几阶曲线,为控制点数-1
int knot_num_; //节点数是分布在0-1之间有多少个点
std::vector<hybrid_astar::Vector2D> control_points_;
std::vector<hybrid_astar::Vector2D> path_points_;
};
定义cpp文件
const std::vector<hybrid_astar::Vector2D>& Bezier::CalculateSpline(
const std::vector<hybrid_astar::Vector2D>& control_points,
const int& knot_number) {
ctrl_num_ = control_points.size();
control_points_ = control_points;
knot_num_ = knot_number;
//点数-1为阶数l
order_ = control_points_.size() - 1;
switch (order_) {
case 2:
CalculateSecond();
break;
case 3:
CalculateCubic();
break;
default:
std::cout << "No define order: " << order_ << std::endl;
break;
}
return path_points_;
}
void Bezier::CalculateSecond() {
if (ctrl_num_ != 3)
return;
path_points_.clear();
double t = 0;
double delta_t = 1.0 / (static_cast<double>(knot_num_));
double f1, f2, f3;
for (double i = 0; i <= knot_num_; ++i) {
t = delta_t * i;
f1 = (1 - t) * (1 - t);
f2 = 2 * (1 - t) * t;
f3 = t * t;
path_points_.push_back(
hybrid_astar::Vector2D(f1 * control_points_[0].getX() +
f2 * control_points_[1].getX() + f3 * control_points_[2].getX(),
f1 * control_points_[0].getY() + f2 * control_points_[1].getY() +
f3 * control_points_[2].getY()));
}
}
void Bezier::CalculateCubic() {
if (ctrl_num_ != 4)
return;
path_points_.clear();
double t = 0;
double delta_t = 1.0 / (static_cast<double>(knot_num_));
double f1, f2, f3, f4;
for (double i = 0; i <= knot_num_; ++i) {
t = delta_t * i;
f1 = (1 - t) * (1 - t) * (1 - t);
f2 = 3 * (1 - t) * (1 - t) * t;
f3 = 3 * (1 - t) * t * t;
f4 = t * t * t;
path_points_.push_back(
hybrid_astar::Vector2D(f1 * control_points_[0].getX() +
f2 * control_points_[1].getX() + f3 * control_points_[2].getX() +
f4 * control_points_[3].getX(),
f1 * control_points_[0].getY() + f2 * control_points_[1].getY() +
f3 * control_points_[2].getY() + f4 * control_points_[3].getY()));
}
}