У меня есть набор контрольных точек, и я пытаюсь нарисовать кубический B-сплайн (степень 3) на основе этих контрольных точек.Проблема, с которой я сталкиваюсь, заключается в том, что моя кривая не соединяется с конечной контрольной точкой, а вместо этого рисует кривую в какой-то другой точке, которая находится в другой области вместе.Точки кривой приближаются к (0, 0)
через определенное время.
Изображение только контрольных точек
Изображение кривой и контрольных точек.Обратите внимание, что кривая правильно начинается в первой контрольной точке, но не заканчивается в последней контрольной точке.
Код, с которым я работаю:
float Stroke::calculate_N(float t, int i, int j, vector<float> knots){
float t_1 = knots[i];
float t_2 = knots[(i + j)];
float t_3 = knots[(i + 1)];
float t_4 = knots[(i + j + 1)];
// Base case of basis function
if (j == 0){
if (t_1 <= t && t < t_3) return 1;
else return 0;
}
float temp1 = (t_2 - t_1 == 0) ? 0 : ((t - t_1) / (t_2 - t_1)) * calculate_N(t, i, j-1, knots);
float temp2 = (t_4 - t_3 == 0) ? 0 : ((t_4 - t) / (t_4 - t_3)) * calculate_N(t, i+1, j-1, knots);
return temp1 + temp2;
}
vector<float> make_knot_vector(int m, int p, int n){
vector<float> knots;
for (int i = 0; i <= p; i++){
knots.push_back(0.0);
}
for (int i = 1; i <= n - p; i++){
knots.push_back((float)i/(float)(n-p+1));
}
for (int i = 0; i <= p; i++){
knots.push_back(1.0);
}
return knots;
}
int main(){
// Init control points
s = Spline();
s.add_control_point(100,100);
s.add_control_point(232,71);
s.add_control_point(148,294);
s.add_control_point(310,115);
s.add_control_point(375,280);
// Get the number of knots based on the number of control points and degree
int num_ctrl_pts = s.get_control_points().size();
float NUM_KNOTS = (float)(num_ctrl_pts + 3 + 1);
// Draw each control point in red
for (auto pt : s.get_control_points()){
int x = pt->get_x();
int y = pt->get_y();
int r = s.get_radius();
vector<vector<float>> circle_points = calc_circ(y, x, r);
int si = circle_points.size();
for (auto circ_point : circle_points){
c->setColor(circ_point[0], circ_point[1], Color(1.0, 0.0, 0.0));
}
}
// Draw the curve
vector<float> knots = make_knot_vector(NUM_KNOTS, 3, num_ctrl_pts);
for (float t = 0.0; t < 1.0; t+= 1.0/1000.0){
Vector sum = Vector(0.0, 0.0);
for (int i = 0;i < num_ctrl_pts; i++){
Vector next = *(s.get_control_points()[i]);
float n = s.calculate_N(t, i, 3, knots);
next = next * n;
sum = sum + next;
}
cout<<"("<<(int)sum.get_x()<<", "<<(int)sum.get_y()<<")"<<endl;
// Draw the curve point in green
vector<vector<float>> circle_points = calc_circ((int)sum.get_y(), (int)sum.get_x(), s.get_radius());
for (auto circ_point : circle_points){
c->setColor(circ_point[0], circ_point[1], Color(0.0, 1.0, 0.0));
}
}
c->writeImage(path + "spline.ppm");
// delete canvas;
return 0;
}