贝塞尔曲线计算方法
class PointF
{
public:
PointF() {};
PointF(double _x, double _y) :
m_x(_x), m_y(_y) {};
PointF operator-(const PointF& rhs) {
PointF tem(this->m_x,this->m_y);
tem.m_x -= rhs.m_x;
tem.m_y -= rhs.m_y;
return tem;
}
PointF operator+(const PointF& rhs) {
PointF tem(this->m_x,this->m_y);
tem.m_x += rhs.m_x;
tem.m_y += rhs.m_y;
return tem;
}
double mod() const { return std::sqrt(m_x * m_x + m_y * m_y); }
double x() const { return m_x; }
double y() const { return m_y; }
public:
double m_x = 0;
double m_y = 0;
};
static void SeerBezier(std::vector<PointF>& path, double &length,PointF PosStart_, PointF ConPoint0_, PointF ConPoint1_, PointF PosEnd_, int num)
{
std::vector<PointF> tmpath;
tmpath.push_back(PosStart_);
for (int i = 1; i < num; ++i) {
double t = (double)i / (double)num;
double x = pow(1 - t, 3) * PosStart_.x() + 3.0 * t * pow(1 - t, 2) * ConPoint0_.x() +
3.0 * pow(t, 2) * (1 - t) * ConPoint1_.x() + pow(t, 3) * PosEnd_.x();
double y = pow(1 - t, 3) * PosStart_.y() + 3.0 * t * pow(1 - t, 2) * ConPoint0_.y() +
3.0 * pow(t, 2) * (1 - t) * ConPoint1_.y() + pow(t, 3) * PosEnd_.y();
tmpath.push_back(PointF(x, y));
}
tmpath.push_back(PosEnd_);
double len = 0.0;
for (int i = 1; i <= num; i++) {
len = len + (tmpath[i] - tmpath[i - 1]).mod();
}
length = len;
int maxnum = std::max(3, std::min(int(length / 25), num));
for (int i = 1; i < maxnum; ++i) {
double t = (double)i / (double)maxnum;
double x = pow(1 - t, 3) * PosStart_.x() + 3.0 * t * pow(1 - t, 2) * ConPoint0_.x() +
3.0 * pow(t, 2) * (1 - t) * ConPoint1_.x() + pow(t, 3) * PosEnd_.x();
double y = pow(1 - t, 3) * PosStart_.y() + 3.0 * t * pow(1 - t, 2) * ConPoint0_.y() +
3.0 * pow(t, 2) * (1 - t) * ConPoint1_.y() + pow(t, 3) * PosEnd_.y();
path.push_back(PointF(x, y));
}
path.push_back(PosEnd_);
}
static void DegenerateBezier(std::vector<PointF>& path, double &length,PointF PosStart_, PointF ConPoint0_, PointF ConPoint1_, PointF PosEnd_, int num)
{
auto getv = [](double p0, double p1, double p2, double p3, double p4, double p5, int num, std::vector<double>& v) {
v.clear();
for (int i = 1; i < num; i++) {
double t = (double)i / (double)num;
double s = 1 - t;
double x = p0 * s * s * s * s * s
+ 5.0 * p1 * s * s * s * s * t
+ 10.0 * p2 * s * s * s * t * t
+ 10.0 * p3 * s * s * t * t * t
+ 5.0 * p4 * s * t *t * t * t
+ p5 * t * t * t * t * t;
v.push_back(x);
}
};
std::vector<double> x;
std::vector<double> y;
getv(PosStart_.x(), ConPoint0_.x(), ConPoint0_.x(), ConPoint1_.x(), ConPoint1_.x(), PosEnd_.x(), num, x);
getv(PosStart_.y(), ConPoint0_.y(), ConPoint0_.y(), ConPoint1_.y(), ConPoint1_.y(), PosEnd_.y(), num, y);
std::vector<PointF> tmpath;
tmpath.push_back(PosStart_);
for (int i = 0; i < x.size(); i++) {
tmpath.emplace_back(PointF(x[i], y[i]));
}
tmpath.push_back(PosEnd_);
double len = 0.0;
for (int i = 1; i <= num; i++) {
len = len + (tmpath[i] - tmpath[i - 1]).mod();
}
length = len;
int maxnum = std::max(3, std::min(int(length / 25 ), num));
x.clear();
y.clear();
getv(PosStart_.x(), ConPoint0_.x(), ConPoint0_.x(), ConPoint1_.x(), ConPoint1_.x(), PosEnd_.x(), maxnum, x);
getv(PosStart_.y(), ConPoint0_.y(), ConPoint0_.y(), ConPoint1_.y(), ConPoint1_.y(), PosEnd_.y(), maxnum, y);
path.clear();
for (int i = 0; i < x.size(); i++) {
path.emplace_back(PointF(x[i], y[i]));
}
path.push_back(PosEnd_);
}