如何 "join" 二次或三次样条曲线?
How can I "join" quadratic or cubic splines?
我有 2 个函数来计算样条曲线上的点,二次曲线或三次曲线:
struct vec2 {float x, y;};
vec2 spline_quadratic(vec2 & a, vec2 & b, vec2 & c, float t) {
return {
(1 - t) * (1 - t) * p1.x + 2 * (1 - t) * t * p2.x + t * t * p3.x,
(1 - t) * (1 - t) * p1.y + 2 * (1 - t) * t * p2.y + t * t * p3.y
};
}
vec2 spline_cubic(vec2 & a, vec2 & b, vec2 & c, vec2 & d, float t){
return {
//B(t) = (1-t)**3 p0 + 3(1 - t)**2 t P1 + 3(1-t)t**2 P2 + t**3 P3
(1 - t) * (1 - t) * (1 - t) * p1.x + 3 * (1 - t) * (1 - t) * t * p2.x + 3 * (1 - t) * t * t * p3.x + t * t * t * p4.x,
(1 - t) * (1 - t) * (1 - t) * p1.y + 3 * (1 - t) * (1 - t) * t * p2.y + 3 * (1 - t) * t * t * p3.y + t * t * t * p4.y
};
是否可以连接点数组的几条曲线?
我正在寻找具有此签名的函数:
vector<vec2> spline_join(vector<vec2> & points, int segments = 16){
vector<vec2> spline_points;
for(int i = 0; i < points.size()-2; ++i){
for(int div = 0; div < segments; ++div){
spline_points.push_back(spline_quadratic(points[0], points[1], points[2], 1.f/segments);
}
}
}
我读到它需要插值,但我不确定...代码会是什么样子?我已经搜索过,但找不到相关问题和答案...
我看到有库,但我正在寻找更短的实现。
编辑:我试过这里的问题和答案,显然这就是我想要的:
Joining B-Spline segments in OpenGL / C++
代码不是很干净,但经过一些清理后,它确实可以工作。
我已经清理了这个答案Joining B-Spline segments in OpenGL / C++
这不是 Hermite 样条,Hermite 样条通过点,B 样条不通过。
这是有效的方法和结果
float B0(float u) {
//return float(pow(u - 1, 3) / 6.0);
// (1-t)*(1-t)*(1-t)/6.f
return float(pow(1-u, 3) / 6.0);
}
float B1(float u) {
return float((3 * pow(u, 3) - 6 * pow(u, 2) + 4) / 6.0);
// (3 * t * t * t - 6 * t * t + 4) / 6
}
float B2(float u) {
return float((-3 * pow(u, 3) + 3 * pow(u, 2) + 3 * u + 1) / 6.0);
// (-3 * t * t * t + 3 * t * t + 3 * t + 1) / 6
}
float B3(float u) {
return float(pow(u, 3) / 6.0);
// t * t * t / 6
}
vector<Vec2> computeBSpline(vector<Vec2>& points) {
vector<Vec2> result;
int MAX_STEPS = 100;
int NUM_OF_POINTS = points.size();
for (int i = 0; i < NUM_OF_POINTS - 3; i++)
{
//cout << "Computing for P" << i << " P " << i + 1 << " P " << i + 2 << " P " << i + 3 << endl;
for (int j = 0; j <= MAX_STEPS; j++)
{
float u = float(j) / float(MAX_STEPS);
float Qx =
B0(u) * points[i].x
+ B1(u) * points[i + 1].x
+ B2(u) * points[i + 2].x
+ B3(u) * points[i + 3].x;
float Qy =
B0(u) * points[i].y
+ B1(u) * points[i + 1].y
+ B2(u) * points[i + 2].y
+ B3(u) * points[i + 3].y;
result.push_back({ Qx, Qy });
//cout << count << '(' << Qx << ", " << Qy << ")\n";
}
}
return result;
}
我有 2 个函数来计算样条曲线上的点,二次曲线或三次曲线:
struct vec2 {float x, y;};
vec2 spline_quadratic(vec2 & a, vec2 & b, vec2 & c, float t) {
return {
(1 - t) * (1 - t) * p1.x + 2 * (1 - t) * t * p2.x + t * t * p3.x,
(1 - t) * (1 - t) * p1.y + 2 * (1 - t) * t * p2.y + t * t * p3.y
};
}
vec2 spline_cubic(vec2 & a, vec2 & b, vec2 & c, vec2 & d, float t){
return {
//B(t) = (1-t)**3 p0 + 3(1 - t)**2 t P1 + 3(1-t)t**2 P2 + t**3 P3
(1 - t) * (1 - t) * (1 - t) * p1.x + 3 * (1 - t) * (1 - t) * t * p2.x + 3 * (1 - t) * t * t * p3.x + t * t * t * p4.x,
(1 - t) * (1 - t) * (1 - t) * p1.y + 3 * (1 - t) * (1 - t) * t * p2.y + 3 * (1 - t) * t * t * p3.y + t * t * t * p4.y
};
是否可以连接点数组的几条曲线?
我正在寻找具有此签名的函数:
vector<vec2> spline_join(vector<vec2> & points, int segments = 16){
vector<vec2> spline_points;
for(int i = 0; i < points.size()-2; ++i){
for(int div = 0; div < segments; ++div){
spline_points.push_back(spline_quadratic(points[0], points[1], points[2], 1.f/segments);
}
}
}
我读到它需要插值,但我不确定...代码会是什么样子?我已经搜索过,但找不到相关问题和答案...
我看到有库,但我正在寻找更短的实现。
编辑:我试过这里的问题和答案,显然这就是我想要的:
Joining B-Spline segments in OpenGL / C++
代码不是很干净,但经过一些清理后,它确实可以工作。
我已经清理了这个答案Joining B-Spline segments in OpenGL / C++
这不是 Hermite 样条,Hermite 样条通过点,B 样条不通过。
这是有效的方法和结果
float B0(float u) {
//return float(pow(u - 1, 3) / 6.0);
// (1-t)*(1-t)*(1-t)/6.f
return float(pow(1-u, 3) / 6.0);
}
float B1(float u) {
return float((3 * pow(u, 3) - 6 * pow(u, 2) + 4) / 6.0);
// (3 * t * t * t - 6 * t * t + 4) / 6
}
float B2(float u) {
return float((-3 * pow(u, 3) + 3 * pow(u, 2) + 3 * u + 1) / 6.0);
// (-3 * t * t * t + 3 * t * t + 3 * t + 1) / 6
}
float B3(float u) {
return float(pow(u, 3) / 6.0);
// t * t * t / 6
}
vector<Vec2> computeBSpline(vector<Vec2>& points) {
vector<Vec2> result;
int MAX_STEPS = 100;
int NUM_OF_POINTS = points.size();
for (int i = 0; i < NUM_OF_POINTS - 3; i++)
{
//cout << "Computing for P" << i << " P " << i + 1 << " P " << i + 2 << " P " << i + 3 << endl;
for (int j = 0; j <= MAX_STEPS; j++)
{
float u = float(j) / float(MAX_STEPS);
float Qx =
B0(u) * points[i].x
+ B1(u) * points[i + 1].x
+ B2(u) * points[i + 2].x
+ B3(u) * points[i + 3].x;
float Qy =
B0(u) * points[i].y
+ B1(u) * points[i + 1].y
+ B2(u) * points[i + 2].y
+ B3(u) * points[i + 3].y;
result.push_back({ Qx, Qy });
//cout << count << '(' << Qx << ", " << Qy << ")\n";
}
}
return result;
}